# Copyright (C) 2020-present MongoDB, Inc.
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the Server Side Public License, version 1,
# as published by MongoDB, Inc.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# Server Side Public License for more details.
#
# You should have received a copy of the Server Side Public License
# along with this program. If not, see
# <http://www.mongodb.com/licensing/server-side-public-license>.
#
# As a special exception, the copyright holders give permission to link the
# code of portions of this program with the OpenSSL library under certain
# conditions as described in each individual source file and distribute
# linked combinations including the program with the OpenSSL library. You
# must comply with the Server Side Public License in all respects for
# all of the code used other than as permitted herein. If you modify file(s)
# with this exception, you may extend this exception to your version of the
# file(s), but you are not obligated to do so. If you do not wish to do so,
# delete this exception statement from your version. If you delete this
# exception statement from all source files in the program, then also delete
# it in the license file.
#

# This file defines types used among various resharding-related IDL structs.

global:
    cpp_namespace: "mongo"

imports:
    - "mongo/db/keypattern.idl"
    - "mongo/db/basic_types.idl"
    - "mongo/s/sharding_types.idl"

enums:
    CoordinatorState:
        description: "The current state of a resharding operation on the coordinator."
        type: string
        values:
            kUnused: "unused"
            kInitializing: "initializing"
            kPreparingToDonate: "preparing-to-donate"
            kCloning: "cloning"
            kApplying: "applying"
            kBlockingWrites: "blocking-writes"
            kAborting: "aborting"
            kCommitting: "committing"
            kQuiesced: "quiesced"
            kDone: "done"

    DonorState:
        description: "The current state of a donor shard for a resharding operation."
        type: string
        values:
            kUnused: "unused"
            kPreparingToDonate: "preparing-to-donate"
            kDonatingInitialData: "donating-initial-data"
            kDonatingOplogEntries: "donating-oplog-entries"
            kPreparingToBlockWrites: "preparing-to-block-writes"
            kError: "error"
            kBlockingWrites: "blocking-writes"
            kDone: "done"

    RecipientState:
        description: "The current state of a recipient shard for a resharding operation."
        type: string
        values:
            kUnused: "unused"
            kAwaitingFetchTimestamp: "awaiting-fetch-timestamp"
            kCreatingCollection: "creating-collection"
            kCloning: "cloning"
            kBuildingIndex: "building-index"
            kApplying: "applying"
            kError: "error"
            kStrictConsistency: "strict-consistency"
            kDone: "done"

    ReshardingOperationStatus:
        description: "The status of the current or most recent resharding operation."
        type: string
        values:
            kSuccess: "success"
            kFailure: "failure"
            kCanceled: "canceled"
            kRunning: "running"
            kInactive: "inactive"

    Provenance:
        description: "The source operation that called this resharding operation."
        type: string
        values:
            kReshardCollection: "reshardCollection"
            kMoveCollection: "moveCollection"
            kUnshardCollection: "unshardCollection"
            kBalancerMoveCollection: "balancerMoveCollection"

structs:
    CommonReshardingMetadata:
        description: "Immutable metadata shared across all node types for a resharding operation."
        generate_comparison_operators: false
        # Use strict:false to avoid complications around upgrade/downgrade. This isn't technically
        # required for resharding because durable state from all resharding operations is cleaned up
        # before the upgrade or downgrade can complete.
        strict: false
        fields:
            _id:
                cpp_name: reshardingUUID
                type: uuid
                description: "A unique identifier for the resharding operation."
            ns:
                cpp_name: sourceNss
                type: namespacestring
                description: "The namespace of the collection being resharded."
            ui:
                cpp_name: sourceUUID
                type: uuid
                description: "The UUID of the original collection being resharded."
            tempNs:
                cpp_name: tempReshardingNss
                type: namespacestring
                description: "The namespace of the temporary resharding collection that exists on
                              recipient shards."
            reshardingKey:
                type: KeyPattern
                description: "The index specification document to use as the new shard key."
            startTime:
                type: date
                description: "Operation start time."
                optional: true
            userReshardingUUID:
                type: uuid
                optional: true
                description: >-
                    The resharding UUID provided by the user, used to identify retries.
            provenance:
                type: Provenance
                description: "The source operation that called this resharding operation."
                optional: true
            implicitlyCreateIndex:
                type: bool
                description: "Whether to create an index on the shard key pattern if the shard key
                              does not already have a support index."
                default: true

    AbortReason:
        description: "Not meant to be used directly. Only use internal fields."
        # Use strict:false to avoid complications around upgrade/downgrade. This setting has no
        # practical effect because this type is only meant to be used as a chained struct with
        # inline_chained_structs:true and only the strictness setting of the wrapping struct type
        # applies.
        strict: false
        fields:
            abortReason:
                type: object_owned
                description: "The error that caused the node to abort the resharding operation. In
                              this case, the node may be a donor shard, recipient shard, or the
                              coordinator itself."
                optional: true

    DonorShardContext:
        description: "Mutable state for a donor shard tracked both locally by a donor shard and
                      remotely by the resharding coordinator."
        inline_chained_structs: true
        chained_structs:
            AbortReason: AbortReasonStruct
        generate_comparison_operators: false
        # Use strict:false to avoid complications around upgrade/downgrade. This isn't technically
        # required for resharding because durable state from all resharding operations is cleaned up
        # before the upgrade or downgrade can complete.
        strict: false
        fields:
            state:
                type: DonorState
                default: kUnused
            minFetchTimestamp:
                type: timestamp
                description: "Timestamp after which this donor shard has guaranteed that oplog
                              entries contain recipient shard information."
                optional: true
            bytesToClone:
                type: long
                description: "Number of bytes on this donor shard in the collection being
                              resharded."
                optional: true
            documentsToClone:
                type: long
                description: "Number of documents on this donor shard in the collection being
                              resharded."
                optional: true
            writesDuringCriticalSection:
                type: long
                description: "Number of writes during critical section on this donor shard."
                optional: true

    DonorShardFetchTimestamp:
        description: "Used for tracking donor min fetch timestamp"
        strict: false
        generate_comparison_operators: false
        fields:
            shardId:
                type: shard_id
                description: "A shard identifier."
            minFetchTimestamp:
                type: timestamp
                optional: true
                description: "Timestamp after which this donor shard has guaranteed that oplog
                                entries contain recipient shard information."

    RecipientShardContext:
        description: "Mutable state for a recipient shard tracked both locally by a recipient shard
                      and remotely by the resharding coordinator."
        inline_chained_structs: true
        chained_structs:
            AbortReason: AbortReasonStruct
        generate_comparison_operators: false
        # Use strict:false to avoid complications around upgrade/downgrade. This isn't technically
        # required for resharding because durable state from all resharding operations is cleaned up
        # before the upgrade or downgrade can complete.
        strict: false
        fields:
            state:
                type: RecipientState
                default: kUnused
            bytesCopied:
                type: long
                description: "Number of bytes copied on this recipient shard."
                optional: true
            oplogFetched:
                type: long
                description: "Number of oplog entries fetched on this recipient shard."
                optional: true
            oplogApplied:
                type: long
                description: "Number of oplog entries applied on this recipient shard."
                optional: true
            totalNumDocuments:
                type: long
                description: "Number of documents on this recipient shard for the resharded collection."
                optional: true
            totalDocumentSize:
                type: long
                description: "Total size of all documents on this recipient shard for the resharded collection."
                optional: true
            numOfIndexes:
                type: long
                description: "Number of indexes on this recipient shard for the resharded collection."
                optional: true

    ReshardingApproxCopySize:
        description: "Not meant to be used directly. Only use internal fields."
        # Use strict:false to avoid complications around upgrade/downgrade. This setting has no
        # practical effect because this type is only meant to be used as a chained struct with
        # inline_chained_structs:true and only the strictness setting of the wrapping struct type
        # applies.
        strict: false
        fields:
            approxDocumentsToCopy:
                type: long
                optional: true
            approxBytesToCopy:
                type: long
                optional: true

    ReshardingSourceId:
        description: "Identifier for a shard involved in a particular resharding operation."
        # Use strict:true because this type is used as the structure for the _id value in documents
        # and requires being an exact match.
        strict: true
        fields:
            reshardingUUID:
                type: uuid
                description: "Identifier for a resharding operation."
            shardId:
                type: shard_id
                description: "A shard identifier."

    ReshardingZoneType:
        description: >-
            Object describing a zone for the collection being resharded using the new shard key.
        # Use strict:false to avoid complications around upgrade/downgrade.
        strict: false
        fields:
            zone:
                type: string
                description: "The zone name."
            min:
                type: object_owned
                description: "The min key of the chunk range assigned to the zone."
            max:
                type: object_owned
                description: "The max key of the chunk range assigned to the zone."

    ReshardedChunk:
        description: "ReshardedChunk"
        fields:
            recipientShardId:
                type: shard_id
                description: "The id of the recipient shard."
            min:
                type: object_owned
                description: "The min key of the chunk range."
            max:
                type: object_owned
                description: "The max key of the chunk range."

    ReshardingMetricsTimeInterval:
        description: "Contains the start and stop time of a resharding operation phase."
        strict: false
        fields:
            start:
                type: date
                description: "The start timestamp."
                optional: true
            stop:
                type: date
                description: "The stop timestamp."
                optional: true

    DocumentSourceReshardingOwnershipMatchSpec:
        description: "A struct representing the information needed for a resharding pipeline to
                      determine which documents belong to a particular shard."
        strict: true
        query_shape_component: true
        fields:
            recipientShardId:
                type: shard_id
                description: "The id of the recipient shard."
                query_shape: anonymize
            reshardingKey:
                type: KeyPattern
                description: "The index specification document to use as the new shard key."
                query_shape: custom
            temporaryReshardingNamespace:
                type: namespacestring
                description: "The namespace of the temporary resharding collection that exists on
                              recipient shards."
                query_shape: custom
                optional: true
    ShardKeyRange:
        description: "A struct to represent the key ranges of shards."
        fields:
            min:
                type: object_owned
                description: "The min key of this shard key range."
                optional: true
            max:
                type: object_owned
                description: "The max key of this shard key range."
                optional: true
            shard:
                type: shard_id
                description: "Id of the shard for this shard key range."
