// Copyright (C) 2024 Quickwit, Inc.
//
// Quickwit is offered under the AGPL v3.0 and as commercial software.
// For commercial licensing, contact us at hello@quickwit.io.
//
// AGPL:
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// 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
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.

syntax = "proto3";

package quickwit.ingest;

import "quickwit/common.proto";

// The corresponding Rust struct [`crate::types::Position`] is defined manually and
// externally provided during code generation (see `build.rs`).
//
// Modify at your own risk.
message Position {
  bytes position = 1;
}

// The corresponding Rust struct [`crate::types::ShardId`] is defined manually and
// externally provided during code generation (see `build.rs`).
//
// Modify at your own risk.
message ShardId {
  bytes shard_id = 1;
}

// Shard primary key.
message ShardPKey {
  quickwit.common.IndexUid index_uid = 1;
  string source_id = 2;
  ShardId shard_id = 3;
}

enum CommitTypeV2 {
  COMMIT_TYPE_V2_UNSPECIFIED = 0;
  COMMIT_TYPE_V2_AUTO = 1;
  COMMIT_TYPE_V2_WAIT_FOR = 2;
  COMMIT_TYPE_V2_FORCE = 3;
}

message DocBatchV2 {
  bytes doc_buffer = 1;
  repeated uint32 doc_lengths = 2;
  repeated quickwit.common.DocUid doc_uids = 3;
}

message MRecordBatch {
  // Buffer of encoded and then concatenated mrecords.
  bytes mrecord_buffer = 1;
  // Lengths of the mrecords in the buffer.
  repeated uint32 mrecord_lengths = 2;
}

enum ShardState {
  SHARD_STATE_UNSPECIFIED = 0;
  // The shard is open and accepts write requests.
  SHARD_STATE_OPEN = 1;
  // The ingester hosting the shard is unavailable.
  SHARD_STATE_UNAVAILABLE = 2;
  // The shard is closed and cannot be written to.
  // It can be safely deleted if the publish position is superior or equal to `~eof`.
  SHARD_STATE_CLOSED = 3;
}

message Shard {
  // Immutable fields
  quickwit.common.IndexUid index_uid = 1;
  string source_id = 2;
  ShardId shard_id = 3;
  // The node ID of the ingester to which all the write requests for this shard should be sent to.
  string leader_id = 4;
  // The node ID of the ingester holding a copy of the data.
  optional string follower_id = 5;

  // Mutable fields
  ShardState shard_state = 8;
  // Position up to which indexers have indexed and published the records stored in the shard.
  // It is updated asynchronously in a best effort manner by the indexers and indicates the position up to which the log can be safely truncated.
  Position publish_position_inclusive = 9;
  // A publish token that ensures only one indexer works on a given shard at a time.
  // For instance, if an indexer goes rogue, eventually the control plane will detect it and assign the shard to another indexer, which will override the publish token.
  optional string publish_token = 10;

  // The UID of the index doc mapping when the shard was created.
  quickwit.common.DocMappingUid doc_mapping_uid = 11;

  // Time when the shard was last updated
  int64 update_timestamp = 12;
}

// A group of shards belonging to the same index and source.
message ShardIds {
  quickwit.common.IndexUid index_uid = 1;
  string source_id = 2;
  repeated ShardId shard_ids = 3;
}

message ShardIdPositions {
  quickwit.common.IndexUid index_uid = 1;
  string source_id = 2;
  repeated ShardIdPosition shard_positions = 3;
}

message ShardIdPosition {
  ShardId shard_id = 1;
  Position publish_position_inclusive = 2;
}

enum ParseFailureReason {
  PARSE_FAILURE_REASON_UNSPECIFIED = 0;
  PARSE_FAILURE_REASON_INVALID_JSON = 1;
  PARSE_FAILURE_REASON_INVALID_SCHEMA = 2;
}

message ParseFailure {
  quickwit.common.DocUid doc_uid = 1;
  ParseFailureReason reason = 2;
  string message = 3;
}
