syntax = "proto3";

package milvus.proto.messages;

option go_package = "github.com/milvus-io/milvus/pkg/v3/proto/messagespb";

import "common.proto";
import "schema.proto";
import "data_coord.proto"; // for SegmentLevel, but it's a basic type should not be in datacoord.proto.
import "index_coord.proto";
import "internal.proto";
import "milvus.proto";
import "rg.proto";
import "google/protobuf/field_mask.proto";

// Message is the basic unit of communication between publisher and consumer.
message Message {
    bytes payload                  = 1;  // message body
    map<string, string> properties = 2;  // message properties
}

// MessageType is the type of message.
enum MessageType {
    Unknown              = 0;
    TimeTick             = 1;
    Insert               = 2;
    Delete               = 3;
    Flush                = 4;
    CreateCollection     = 5;
    DropCollection       = 6;
    CreatePartition      = 7;
    DropPartition        = 8;
    ManualFlush          = 9;
    CreateSegment        = 10;
    Import               = 11;
    SchemaChange         = 12 [deprecated = true]; // merged into AlterCollection
    AlterCollection      = 13;
    AlterLoadConfig      = 14; // load config is simple, so CreateLoadConfig and AlterLoadConfig share one message.
    DropLoadConfig       = 15;
    CreateDatabase       = 16;
    AlterDatabase        = 17;
    DropDatabase         = 18;
    AlterAlias           = 19; // alias is simple, so CreateAlias and AlterAlias share one message.
    DropAlias            = 20;
    RestoreRBAC          = 21;
    AlterUser            = 22; // user is simple, so CreateUser and AlterUser share one message.
    DropUser             = 23;
    AlterRole            = 24; // role is simple, so CreateRole and AlterRole share one message.
    DropRole             = 25;
    AlterUserRole        = 26; // user role is simple, so CreateUserRole and AlterUserRole share one message.
    DropUserRole         = 27;
    AlterPrivilege       = 28; // privilege is simple, so CreatePrivilege and AlterPrivilege share one message.
    DropPrivilege        = 29;
    AlterPrivilegeGroup  = 30; // privilege group is simple, so CreatePrivilegeGroup and AlterPrivilegeGroup share one message.
    DropPrivilegeGroup   = 31;
    AlterResourceGroup   = 32; // resource group is simple, so CreateResourceGroup and AlterResourceGroup share one message.
    DropResourceGroup    = 33;
    CreateIndex          = 34;
    AlterIndex           = 35;
    DropIndex            = 36;
    FlushAll             = 37;
    TruncateCollection   = 38;
    RestoreSnapshot              = 39;
    CreateSnapshot               = 40;
    DropSnapshot                 = 41;
    BatchUpdateManifest          = 42;
    RefreshExternalCollection    = 43;
    DropSnapshotsByCollection    = 44;
    CommitImport                 = 45;
    RollbackImport               = 46;

    // AlterWAL is used to alter the wal configuration to the current cluster.
    AlterWAL             = 700;

    // AlterReplicateConfig is used to alter the replicate configuration to the current cluster.
    // When the AlterReplicateConfig message is received, the replication topology is changed.
    // Maybe some cluster give up the leader role, no any other message will be received from this cluster.
    // So leader will stop writing message into wal and stop replicating any message to the other cluster,
    // and the follower will stop receiving any message from the old leader.
    // New leader will start to write message into wal and start replicating message to the other cluster.
    AlterReplicateConfig = 800;

    // begin transaction message is only used for transaction, once a begin
    // transaction message is received, all messages combined with the
    // transaction message cannot be consumed until a CommitTxn message
    // is received.
    BeginTxn = 900;
    // commit transaction message is only used for transaction, once a commit
    // transaction message is received, all messages combined with the
    // transaction message can be consumed, the message combined with the
    // transaction which is received after the commit transaction message will
    // be drop.
    CommitTxn = 901;
    // rollback transaction message is only used for transaction, once a
    // rollback transaction message is received, all messages combined with the
    // transaction message can be discarded, the message combined with the
    // transaction which is received after the rollback transaction message will
    // be drop.
    RollbackTxn = 902;
    // txn message is a set of messages combined by multiple messages in a
    // transaction. the txn properties is consist of the begin txn message and
    // commit txn message.
    Txn = 999;
}

///
/// Message Payload Definitions
/// Some message payload is defined at msg.proto at milvus-proto for
/// compatibility.
/// 1. InsertRequest
/// 2. DeleteRequest
/// 3. TimeTickRequest
/// 4. CreateCollectionRequest
/// 5. DropCollectionRequest
/// 6. CreatePartitionRequest
/// 7. DropPartitionRequest
///

// FlushMessageBody is the body of flush message.
message FlushMessageBody {}

// ManualFlushMessageBody is the body of manual flush message.
message ManualFlushMessageBody {}

// CreateSegmentMessageBody is the body of create segment message.
message CreateSegmentMessageBody {}

// BeginTxnMessageBody is the body of begin transaction message.
// Just do nothing now.
message BeginTxnMessageBody {}

// CommitTxnMessageBody is the body of commit transaction message.
// Just do nothing now.
message CommitTxnMessageBody {}

// RollbackTxnMessageBody is the body of rollback transaction message.
// Just do nothing now.
message RollbackTxnMessageBody {}

// TxnMessageBody is the body of transaction message.
// A transaction message is combined by multiple messages.
// It's only can be seen at consume side.
// All message in a transaction message only has same timetick which is equal to
// the CommitTransationMessage.
message TxnMessageBody {
    repeated Message messages = 1;
}

///
/// Message Header Definitions
/// Used to fast handling at streaming node write ahead.
/// The header should be simple and light enough to be parsed.
/// Do not alter too much information in the header if unnecessary.
///

// TimeTickMessageHeader just nothing.
message TimeTickMessageHeader {}

// InsertMessageHeader is the header of insert message.
message InsertMessageHeader {
    int64 collection_id                            = 1;
    repeated PartitionSegmentAssignment partitions = 2;
    // optional so consumers can distinguish omitted (legacy producer) from explicit value.
    optional int32 schema_version                  = 3;
}

// PartitionSegmentAssignment is the segment assignment of a partition.
message PartitionSegmentAssignment {
    int64 partition_id                   = 1;
    uint64 rows                          = 2;
    uint64 binary_size                   = 3;
    SegmentAssignment segment_assignment = 4;
}

// SegmentAssignment is the assignment of a segment.
message SegmentAssignment {
    int64 segment_id = 1;
}

// DeleteMessageHeader
message DeleteMessageHeader {
    int64 collection_id = 1;
    uint64 rows = 2;
}

// FlushMessageHeader just nothing.
message FlushMessageHeader {
    int64 collection_id = 1;
    int64 partition_id = 2;
    int64 segment_id = 3;
}

// CreateSegmentMessageHeader just nothing.
message CreateSegmentMessageHeader {
    int64 collection_id     = 1;
    int64 partition_id      = 2;
    int64 segment_id        = 3;
    int64 storage_version   = 4; // the storage version of the segment.
    uint64 max_segment_size = 5; // the max size bytes of the segment.
    uint64 max_rows         = 6; // the max rows of the segment.
    data.SegmentLevel level = 7; // the level of the segment.
    int32 schema_version   = 8;
}

message ManualFlushMessageHeader {
    int64 collection_id = 1;
    uint64 flush_ts     = 2;
    repeated int64 segment_ids   = 3; // the segment ids to be flushed, will be filled by wal shard manager.
}

// CreateCollectionMessageHeader is the header of create collection message.
message CreateCollectionMessageHeader {
    int64 collection_id          = 1;
    repeated int64 partition_ids = 2;
    int64 db_id                  = 3;
}

// DropCollectionMessageHeader is the header of drop collection message.
message DropCollectionMessageHeader {
    int64 collection_id = 1;
    int64 db_id = 2;
}

// CreatePartitionMessageHeader is the header of create partition message.
message CreatePartitionMessageHeader {
    int64 collection_id = 1;
    int64 partition_id  = 2;
}

// DropPartitionMessageHeader is the header of drop partition message.
message DropPartitionMessageHeader {
    int64 collection_id = 1;
    int64 partition_id  = 2;
}

// AlterReplicateConfigMessageHeader is the header of alter replicate configuration message.
message AlterReplicateConfigMessageHeader {
    common.ReplicateConfiguration replicate_configuration = 1;
    // is_pchannel_increasing is set to true when this config change only adds new pchannels
    // (append-only growth). When set, the secondary uses the new config from the message header
    // (instead of the current config) to map all broadcast channels including newly added ones,
    // and CDC uses nil checkpoint for new pchannels.
    bool is_pchannel_increasing = 2;
    bool force_promote = 3;  // indicates this is a forced promote to primary
    bool ignore = 4;         // if true, this message should be ignored during processing
}

// AlterReplicateConfigMessageBody is the body of alter replicate configuration message.
message AlterReplicateConfigMessageBody {
}

// BeginTxnMessageHeader is the header of begin transaction message.
// Just do nothing now.
// Add Channel info here to implement cross pchannel transaction.
message BeginTxnMessageHeader {
    // the max milliseconds to keep alive of the transaction.
    // the keepalive_milliseconds is never changed in a transaction by now,
    int64 keepalive_milliseconds = 1;
}

// CommitTxnMessageHeader is the header of commit transaction message.
// Just do nothing now.
message CommitTxnMessageHeader {}

// RollbackTxnMessageHeader is the header of rollback transaction
// message.
// Just do nothing now.
message RollbackTxnMessageHeader {}

// TxnMessageHeader is the header of transaction message.
// Just do nothing now.
message TxnMessageHeader {}

message ImportMessageHeader {}

// SchemaChangeMessageHeader is the header of CollectionSchema update message.
message SchemaChangeMessageHeader{
    int64 collection_id = 1;
    repeated int64 flushed_segment_ids = 2; // will be filled by wal shard manager.
}

// SchemaChangeMessageBody is the body of CollectionSchema update message.
message SchemaChangeMessageBody{
    schema.CollectionSchema schema = 1;
}

// AlterCollectionMessageHeader is the header of alter collection message.
message AlterCollectionMessageHeader {
    int64 db_id                  = 1;
    int64 collection_id          = 2;
    google.protobuf.FieldMask update_mask = 3;
    CacheExpirations cache_expirations = 4;
    repeated int64 flushed_segment_ids = 5; // will be filled by wal shard manager.
    repeated int64 dropped_field_ids = 6; // field IDs removed by this alter operation, used to cascade-delete indexes in ack callback.
}

// AlterCollectionMessageBody is the body of alter collection message.
message AlterCollectionMessageBody {
    AlterCollectionMessageUpdates updates = 1;
}

// AlterCollectionMessageUpdates is the updates of alter collection message.
message AlterCollectionMessageUpdates {
    int64 db_id                               = 1; // collection db id should be updated.
    string db_name                            = 2; // collection db name should be updated.
    string collection_name                    = 3; // collection name should be updated.
    string description                        = 4; // collection description should be updated.
    schema.CollectionSchema schema            = 5; // collection schema should be updated.
    common.ConsistencyLevel consistency_level = 6; // consistency level should be updated.
    repeated common.KeyValuePair properties   = 7; // collection properties should be updated.
    AlterLoadConfigOfAlterCollection alter_load_config = 8; // alter load config of alter collection.
    // Index meta bound to newly added function-output/vector fields.
    // Fully materialized (index id/name allocated, params validated) at DDL prepare
    // stage BEFORE broadcast; applied atomically with the schema in the ack callback.
    repeated index.FieldIndex bound_field_indexes = 9;
}

// AlterLoadConfigOfAlterCollection is the body of alter load config of alter collection message.
message AlterLoadConfigOfAlterCollection {
    int32 replica_number = 1;
    repeated string resource_groups = 2;
}

// AlterLoadConfigMessageHeader is the header of alter load config message.
message AlterLoadConfigMessageHeader {
    int64 db_id = 1;
    int64 collection_id = 2; // the collection id that has to be loaded.
    repeated int64 partition_ids = 3; // the partition ids that has to be loaded, empty means no partition has to be loaded.
    repeated LoadFieldConfig load_fields = 4; // the field id that has to be loaded.
    repeated LoadReplicaConfig replicas = 5; // the replicas that has to be loaded.
    bool user_specified_replica_mode = 6; // whether the replica mode is user specified.
    bool use_local_replica_config = 7; // when true, use local cluster-level replica config instead of the replicas field above.
}

// AlterLoadConfigMessageBody is the body of alter load config message.
message AlterLoadConfigMessageBody {
}

// LoadFieldConfig is the config to load fields.
message LoadFieldConfig {
    int64 field_id = 1;
    int64 index_id = 2;
}

// LoadReplicaConfig is the config of a replica.
message LoadReplicaConfig {
    int64 replica_id = 1;
    string resource_group_name = 2;
    common.LoadPriority priority = 3;
}

message DropLoadConfigMessageHeader {
    int64 db_id = 1;
    int64 collection_id = 2;
}

message DropLoadConfigMessageBody {}

// CreateDatabaseMessageHeader is the header of create database message.
message CreateDatabaseMessageHeader {
    string db_name = 1;
    int64 db_id = 2;
}

// CreateDatabaseMessageBody is the body of create database message.
message CreateDatabaseMessageBody {
    repeated common.KeyValuePair properties = 1;
}

// AlterDatabaseMessageHeader is the header of alter database message.
message AlterDatabaseMessageHeader {
    string db_name = 1;
    int64 db_id = 2;
}

// AlterDatabaseMessageBody is the body of alter database message.
message AlterDatabaseMessageBody {
    repeated common.KeyValuePair properties = 1;
    AlterLoadConfigOfAlterDatabase alter_load_config = 2;
}

// AlterLoadConfigOfAlterDatabase is the body of alter load config of alter database message.
// When the database's resource group or replica number is changed, the load config of all collection in database will be updated.
message AlterLoadConfigOfAlterDatabase {
    repeated int64 collection_ids = 1;
    int32 replica_number = 2;
    repeated string resource_groups = 3;
}

// DropDatabaseMessageHeader is the header of drop database message.
message DropDatabaseMessageHeader {
    string db_name = 1;
    int64 db_id = 2;
}

// DropDatabaseMessageBody is the body of drop database message.
message DropDatabaseMessageBody {
}

// AlterAliasMessageHeader is the header of alter alias message.
message AlterAliasMessageHeader {
    int64 db_id = 1;
    string db_name = 2;
    int64 collection_id = 3;
    string collection_name = 4;
    string alias = 5;
    // The collection the alias pointed to BEFORE this alter. Sentinel-encoded:
    //   > 0  the known old target -- cache expiration evicts it by id;
    //   == 0 UNKNOWN: either a new AlterAlias whose broadcast could not resolve
    //        the old target, OR an older producer that predates this field. The
    //        proxy falls back to an O(N) holder scan, so 0 is the safe default;
    //   < 0  the "no old target" sentinel that CreateAlias sets -- it provably
    //        has none, so it must NOT trigger the scan. A CreateAlias producer
    //        MUST use this, NOT 0 (0 would O(N)-scan every create).
    // Carried in the header -- computed once under the broadcaster's database
    // lock -- so cache expiration can evict the old target by id even when a
    // concurrent describe has already re-pointed the proxy's alias resolution to
    // the new target, and so replaying the message stays deterministic.
    int64 old_collection_id = 6;
}

// AlterAliasMessageBody is the body of alter alias message.
message AlterAliasMessageBody {
}

// DropAliasMessageHeader is the header of drop alias message.
message DropAliasMessageHeader {
    int64 db_id = 1;
    string db_name = 2;
    string alias = 3;
}

// DropAliasMessageBody is the body of drop alias message.
message DropAliasMessageBody {
}

message CreateUserMessageHeader {
    milvus.UserEntity user_entity = 1;
}

message CreateUserMessageBody {
    internal.CredentialInfo credential_info = 1;
}

// AlterUserMessageHeader is the header of alter user message.
message AlterUserMessageHeader {
    milvus.UserEntity user_entity = 1;
}

// AlterUserMessageBody is the body of alter user message.
message AlterUserMessageBody {
    internal.CredentialInfo credential_info = 1;
}

// DropUserMessageHeader is the header of drop user message.
message DropUserMessageHeader {
    string user_name = 1;
}

// DropUserMessageBody is the body of drop user message.
message DropUserMessageBody {}

// AlterRoleMessageHeader is the header of alter role message.
message AlterRoleMessageHeader {
    milvus.RoleEntity role_entity = 1;
}

// AlterRoleMessageBody is the body of alter role message.
message AlterRoleMessageBody {
}

// DropRoleMessageHeader is the header of drop role message.
message DropRoleMessageHeader {
    string role_name = 1;
    bool force_drop  = 2; // if true, the role will be dropped even if it has privileges.
}

// DropRoleMessageBody is the body of drop role message.
message DropRoleMessageBody {} 

// RoleBinding is the binding of user and role.
message RoleBinding {
    milvus.UserEntity user_entity = 1;
    milvus.RoleEntity role_entity = 2;
}

// AlterUserRoleMessageHeader is the header of alter user role message.
message AlterUserRoleMessageHeader {
    RoleBinding role_binding = 1; // TODO: support multiple role and user bindings in future.
}

// AlterUserRoleMessageBody is the body of alter user role message.
message AlterUserRoleMessageBody {}

// DropUserRoleMessageHeader is the header of drop user role message.
message DropUserRoleMessageHeader {
    RoleBinding role_binding = 1; // TODO: support multiple role and user bindings in future.
}

// DropUserRoleMessageBody is the body of drop user role message.
message DropUserRoleMessageBody {}

// RestoreRBACMessageHeader is the header of restore rbac message.
message RestoreRBACMessageHeader {
}

// RestoreRBACMessageBody is the body of restore rbac message.
message RestoreRBACMessageBody {
    milvus.RBACMeta rbac_meta = 1;
}

// AlterPrivilegeMessageHeader is the header of grant privilege message.
message AlterPrivilegeMessageHeader {
    milvus.GrantEntity entity = 1;
}

// AlterPrivilegeMessageBody is the body of grant privilege message.
message AlterPrivilegeMessageBody {
}

// DropPrivilegeMessageHeader is the header of revoke privilege message.
message DropPrivilegeMessageHeader {
    milvus.GrantEntity entity = 1;
}

// DropPrivilegeMessageBody is the body of revoke privilege message.
message DropPrivilegeMessageBody {} 

// AlterPrivilegeGroupMessageHeader is the header of alter privilege group message.
message AlterPrivilegeGroupMessageHeader {
    milvus.PrivilegeGroupInfo privilege_group_info = 1; // if privileges is empty, new privilege group will be created.
}

// AlterPrivilegeGroupMessageBody is the body of alter privilege group message.
message AlterPrivilegeGroupMessageBody {}

// DropPrivilegeGroupMessageHeader is the header of drop privilege group message.
message DropPrivilegeGroupMessageHeader {
    milvus.PrivilegeGroupInfo privilege_group_info = 1; // if privileges is empty, privilege group will be dropped.
}

// DropPrivilegeGroupMessageBody is the body of drop privilege group message.
message DropPrivilegeGroupMessageBody {}

// AlterResourceGroupMessageHeader is the header of alter resource group message.
message AlterResourceGroupMessageHeader {
    map<string, rg.ResourceGroupConfig> resource_group_configs = 3;
}

// AlterResourceGroupMessageBody is the body of alter resource group message.
message AlterResourceGroupMessageBody {}

// DropResourceGroupMessageHeader is the header of drop resource group message.
message DropResourceGroupMessageHeader {
    string resource_group_name = 1;
}

// DropResourceGroupMessageBody is the body of drop resource group message.
message DropResourceGroupMessageBody {
}

// CreateIndexMessageHeader is the header of create index message.
message CreateIndexMessageHeader {
    int64 db_id = 1;
    int64 collection_id = 2;
    int64 field_id = 3;
    int64 index_id = 4;
    string index_name = 5;
}

// CreateIndexMessageBody is the body of create index message.
message CreateIndexMessageBody {
    index.FieldIndex field_index = 1;
}

// AlterIndexMessageHeader is the header of alter index message.
message AlterIndexMessageHeader {
    int64 collection_id = 1;
    repeated int64 index_ids = 2;
}

// AlterIndexMessageBody is the body of alter index message.
message AlterIndexMessageBody {
    repeated index.FieldIndex field_indexes = 1;
}

// DropIndexMessageHeader is the header of drop index message.
message DropIndexMessageHeader {
    int64 collection_id = 1;
    repeated int64 index_ids = 2; // drop all indexes if empty.
}

// DropIndexMessageBody is the body of drop index message.
message DropIndexMessageBody {}

// CreateSnapshotMessageHeader is the header of create snapshot message.
// Contains all fields from CreateSnapshotRequest (except base).
// snapshot_id is allocated in the callback.
message CreateSnapshotMessageHeader {
    int64 collection_id = 1;
    string name         = 2;
    string description  = 3;
    int64 compaction_protection_seconds = 4; // duration in seconds to protect referenced segments from compaction
}

// CreateSnapshotMessageBody is the body of create snapshot message.
// Empty - all info is in header.
message CreateSnapshotMessageBody {}

// DropSnapshotMessageHeader is the header of drop snapshot message.
// No collection lock needed - dropping snapshot only affects snapshot metadata.
message DropSnapshotMessageHeader {
    string name = 1;
    int64 collection_id = 2; // collection id for per-collection name uniqueness
}

// DropSnapshotMessageBody is the body of drop snapshot message.
// Empty - all info is in header.
message DropSnapshotMessageBody {}

// DropSnapshotsByCollectionMessageHeader is the header of drop-snapshots-by-collection message.
// Used by drop collection callback to cascade-delete all snapshots of a collection.
message DropSnapshotsByCollectionMessageHeader {
    int64 collection_id = 1;
}

// DropSnapshotsByCollectionMessageBody is the body of drop-snapshots-by-collection message.
// Empty - all info is in header.
message DropSnapshotsByCollectionMessageBody {}

// RestoreSnapshotMessageHeader is the header of restore snapshot message.
// Used by DDL callback to restore indexes and data after collection is created.
message RestoreSnapshotMessageHeader {
    string snapshot_name = 1;    // Name of the snapshot to restore
    int64 collection_id = 2;     // Target collection ID (already created)
    int64 job_id = 3;            // Pre-allocated job ID for idempotency
    int64 source_collection_id = 4; // Source collection ID for per-collection snapshot name lookup
    int64 pin_id = 5;            // Pin ID claimed on source snapshot at phase 0, transferred to the copy segment job
    bool external = 6;           // True for external snapshot restore
    string snapshot_s3_location = 7; // Metadata file path for external snapshot restore
    string external_spec = 8; // Optional external storage spec for external snapshot restore
}

// RestoreSnapshotMessageBody is the body of restore snapshot message.
// Empty - all info is read from snapshot by snapshot_name.
message RestoreSnapshotMessageBody {}

message AlterWALMessageHeader {
    common.WALName target_wal_name = 1; // Specifies the target WALName for the alter operation.
    map<string, string> config = 2; // Contains additional configuration parameters for the WAL alter operation.
}

message AlterWALMessageBody {}

// RefreshExternalCollectionMessageHeader is the header of refresh external collection message.
// Used by DDL callback to trigger external collection data refresh.
message RefreshExternalCollectionMessageHeader {
    int64 collection_id = 1;       // Collection ID to refresh
    string collection_name = 2;    // Collection name
    int64 job_id = 3;              // Pre-allocated job ID for idempotency
    string external_source = 4;    // External data source type
    string external_spec = 5;      // External data specification
}

// RefreshExternalCollectionMessageBody is the body of refresh external collection message.
// Empty - all info is in header.
message RefreshExternalCollectionMessageBody {}

// CommitImportMessageHeader is the header of commit import message.
message CommitImportMessageHeader {
    int64 collection_id = 1;
    int64 job_id        = 2;
}

// CommitImportMessageBody is the body of commit import message.
// Empty - all info is in header.
message CommitImportMessageBody {}

// RollbackImportMessageHeader is the header of rollback import message.
message RollbackImportMessageHeader {
    int64 collection_id = 1;
    int64 job_id        = 2;
}

// RollbackImportMessageBody is the body of rollback import message.
// Empty - all info is in header.
message RollbackImportMessageBody {}

// CacheExpirations is the cache expirations of proxy collection meta cache.
message CacheExpirations {
    repeated CacheExpiration cache_expirations = 1;
}

// CacheExpiration is the cache expiration of proxy collection meta cache.
message CacheExpiration {
    oneof cache {
        // LegacyProxyCollectionMetaCache is the cache expiration of legacy proxy collection meta cache.
        LegacyProxyCollectionMetaCache legacy_proxy_collection_meta_cache = 1;
    }
}

// LegacyProxyCollectionMetaCache is the cache expiration of legacy proxy collection meta cache.
message LegacyProxyCollectionMetaCache {
    string db_name = 1;
    string collection_name = 2;
    int64 collection_id = 3;
    string partition_name = 4;
    common.MsgType msg_type = 5;
}

///
/// Message Extra Response
/// Used to add extra information when response to the client.
///
///

// ManualFlushExtraResponse is the extra response of manual flush message.
message ManualFlushExtraResponse {
    repeated int64 segment_ids = 1;
}

message FlushAllMessageHeader {}

message FlushAllMessageBody {}

// TxnContext is the context of transaction.
// It will be carried by every message in a transaction.
message TxnContext {
    // the unique id of the transaction.
    // the txn_id is never changed in a transaction.
    int64 txn_id = 1;
    // the next keep alive timeout of the transaction.
    // after the keep alive timeout, the transaction will be expired.
    int64 keepalive_milliseconds = 2;
}

enum TxnState {
    // should never be used.
    TxnUnknown = 0;
    // the transaction is in flight.
    TxnInFlight = 1;
    // the transaction is on commit.
    TxnOnCommit = 2;
    // the transaction is committed.
    TxnCommitted = 3;
    // the transaction is on rollback.
    TxnOnRollback = 4;
    // the transaction is rollbacked.
    TxnRollbacked = 5;
}

// RMQMessageLayout is the layout of message for RMQ.
message RMQMessageLayout {
    bytes payload                  = 1;  // message body
    map<string, string> properties = 2;  // message properties
}

// BroadcastHeader is the common header of broadcast message.
message BroadcastHeader {
    uint64 broadcast_id = 1;
    repeated string vchannels = 2;
    repeated ResourceKey Resource_keys = 3; // the resource key of the broadcast message.
    // Once the broadcast is sent, the resource of resource key will be hold.
    // New broadcast message with the same resource key will be rejected.
    // And the user can watch the resource key to known when the resource is released.
    bool ack_sync_up = 4; // whether the broadcast operation is need to be synced up between the streaming node and the coordinator.
    // If the ack_sync_up is false, the broadcast operation will be acked once the recovery storage see the message at current vchannel,
    // the fast ack operation can be applied to speed up the broadcast operation.
    // If the ack_sync_up is true, the broadcast operation will be acked after the checkpoint of current vchannel reach current message.
    // the fast ack operation can not be applied to speed up the broadcast operation, because the ack operation need to be synced up with streaming node.
    // e.g. if truncate collection operation want to call ack once callback after the all segment are flushed at current vchannel,
    // it should set the ack_sync_up to be true.
}

// ReplicateHeader is the header of replicate message.
message ReplicateHeader {
    string cluster_id    = 1; // the cluster id of source cluster
    common.MessageID message_id = 2; // the message id of replicate msg from source cluster
    common.MessageID last_confirmed_message_id = 3; // the last confirmed message id of replicate msg from source cluster
    uint64 time_tick     = 4; // the time tick of replicate msg from source cluster
    string vchannel      = 5; // the vchannel of replicate msg from source cluster
}

// ResourceDomain is the domain of resource hold.
enum ResourceDomain {
    ResourceDomainUnknown = 0; // should never be used.
    ResourceDomainImportJobID = 1 [deprecated = true]; // the domain of import job id.
    ResourceDomainCollectionName = 2; // the domain of collection name.
    ResourceDomainDBName = 3; // the domain of db name.
    ResourceDomainPrivilege = 4; // the domain of privilege.
    ResourceDomainSnapshotName = 5; // the domain of snapshot name.
    ResourceDomainCluster = 127; // the domain of full cluster.
}

// ResourceKey is the key for resource hold.
// It's used to implement the resource acquirition mechanism for broadcast message.
// The key should be a unique identifier of the resource for different domain.
message ResourceKey {
    ResourceDomain domain = 1;
    string key = 2;
    bool shared = 3; // whether the resource is shared, 
    // if true, the resource is shared by multiple broadcast message,
    // otherwise, the resource is exclusive to the broadcast message.
}

// CipherHeader is the header of a message that is encrypted.
message CipherHeader {
    int64 ez_id = 1; // related to the encryption zone id
    int64 collection_id = 2; // related to the collection id
    bytes safe_key = 3; // the safe key
    int64 payload_bytes = 4; // the size of the payload before encryption
}

// TraceContextHeader carries the trace context subset (trace_id, span_id,
// flags) stored on a message. Tracestate is intentionally not persisted.
// Serialized into Properties under reserved key `_tc` so that consumers on
// the other side of an RPC / persistence boundary can stitch spans into the
// correct parent-child tree.
// See docs/agent_guides/streaming-system/wal/tracing.md for details.
message TraceContextHeader {
    bytes  trace_id = 1;  // 16 bytes
    bytes  span_id  = 2;  // 8 bytes
    uint32 flags    = 3;  // W3C TraceFlags (sampled bit)
}

// TruncateCollectionMessageHeader is the header of truncate collection message.
message TruncateCollectionMessageHeader {
    int64 db_id = 1;
    int64 collection_id = 2;
    repeated int64 segment_ids = 3;
}

// TruncateCollectionMessageBody is the body of truncate collection message.
message TruncateCollectionMessageBody {}

// BatchUpdateManifestMessageHeader is the header of batch update manifest message.
message BatchUpdateManifestMessageHeader {
    int64 collection_id = 1;
}

// BatchUpdateManifestMessageBody is the body of batch update manifest message.
message BatchUpdateManifestMessageBody {
    repeated BatchUpdateManifestItem items = 1;
}

// BatchUpdateManifestItem is an item in batch update manifest message.
// Either manifest_version (V3 segments) or v2_column_groups (V2 segments) is
// populated. Items with both fields set are rejected by the callback.
message BatchUpdateManifestItem {
    int64 segment_id = 1;
    // V3 path: advance the segment's manifest pointer to this version.
    int64 manifest_version = 2;
    // V2 path: upsert one or more column groups on the segment's FieldBinlogs.
    BatchUpdateManifestV2ColumnGroups v2_column_groups = 3;
}

// BatchUpdateManifestV2ColumnGroups carries a V2 segment column-group upsert.
// Keyed by the top-level fieldID of the group; value.FieldID must equal the key.
message BatchUpdateManifestV2ColumnGroups {
    map<int64, data.FieldBinlog> column_groups = 1;
}
