/// A consistent view of the state of the ledger

syntax = "proto3";

package utxorpc.v1beta.query;

import "google/protobuf/field_mask.proto";
import "utxorpc/v1beta/cardano/cardano.proto";

// Represents a specific point in the blockchain.
message ChainPoint {
  uint64 slot = 1; // Slot number.
  bytes hash = 2; // Block hash.
  uint64 height = 3; // Block height.
  uint64 timestamp = 4; // Block ms timestamp
}

message AnyChainBlock {
  bytes native_bytes = 1; // Original bytes as defined by the chain
  oneof chain {
    utxorpc.v1beta.cardano.Block cardano = 2; // A parsed Cardano block.
  }
}

// Represents a reference to a transaction output
message TxoRef {
  bytes hash = 1; // Tx hash.
  uint32 index = 2; // Output index.
}

// Request to get the chain parameters
message ReadParamsRequest {
  google.protobuf.FieldMask field_mask = 1; // Field mask to selectively return fields in the parsed response.
}

// Request to get the chain config
message ReadGenesisRequest {
  google.protobuf.FieldMask field_mask = 1; // Field mask to selectively return fields in the parsed response.
}

// Request to get the era summary
message ReadEraSummaryRequest {
  google.protobuf.FieldMask field_mask = 1; // Field mask to selectively return fields in the parsed response.
}

// Response containing the genesis configs
message ReadGenesisResponse {
  bytes genesis = 1; // genesis hash for the chain
  string caip2 = 2; // the caip-2 ID for this network
  oneof config {
    utxorpc.v1beta.cardano.Genesis cardano = 3; // Cardano genesis
  }
}

// Response containing the era summaries
message ReadEraSummaryResponse {
  oneof summary {
    utxorpc.v1beta.cardano.EraSummaries cardano = 1; // Cardano era summaries
  }
}

// An evenlope that holds parameter data from any of the compatible chains
message AnyChainParams {
  oneof params {
    utxorpc.v1beta.cardano.PParams cardano = 1; // Cardano parameters
  }
}

// Response containing the chain parameters
message ReadParamsResponse {
  AnyChainParams values = 1; // The value of the parameters.
  ChainPoint ledger_tip = 2; // The chain point that represent the ledger current position.
}

// An evenlope that holds an UTxO patterns from any of compatible chains
message AnyUtxoPattern {
  oneof utxo_pattern {
    utxorpc.v1beta.cardano.TxOutputPattern cardano = 1;
  }
}

// Represents a simple utxo predicate that can composed to create more complex ones
message UtxoPredicate {
  optional AnyUtxoPattern match = 1; // Predicate is true if tx exhibits pattern.
  repeated UtxoPredicate not = 2; // Predicate is true if tx doesn't exhibit pattern.
  repeated UtxoPredicate all_of = 3; // Predicate is true if utxo exhibits all of the patterns.
  repeated UtxoPredicate any_of = 4; // Predicate is true if utxo exhibits any of the patterns.
}

// An evenlope that holds an UTxO from any of compatible chains
message AnyUtxoData {
  bytes native_bytes = 1; // Original bytes as defined by the chain
  TxoRef txo_ref = 2; // Hash of the previous transaction.
  oneof parsed_state {
    utxorpc.v1beta.cardano.TxOutput cardano = 3; // A cardano UTxO
  }
  ChainPoint block_ref = 4; // The chain point that represents the block this UTxO was created in.
}

// Request to get specific UTxOs
message ReadUtxosRequest {
  repeated TxoRef keys = 1; // List of keys UTxOs.
  google.protobuf.FieldMask field_mask = 2; // Field mask to selectively return fields.
}

// Response containing the UTxOs associated with the requested addresses.
message ReadUtxosResponse {
  repeated AnyUtxoData items = 1; // List of UTxOs.
  ChainPoint ledger_tip = 2; // The chain point that represent the ledger current position.
}

// Request to search for UTxO based on a pattern.
message SearchUtxosRequest {
  optional UtxoPredicate predicate = 1; // Pattern to match UTxOs by.
  google.protobuf.FieldMask field_mask = 2; // Field mask to selectively return fields.
  optional int32 max_items = 3; // The maximum number of items to return.
  optional string start_token = 4; // The next_page_token value returned from a previous request, if any.
}

// Response containing the UTxOs that match the requested addresses.
message SearchUtxosResponse {
  repeated AnyUtxoData items = 1; // List of UTxOs.
  ChainPoint ledger_tip = 2; // The chain point that represent the ledger current position.
  optional string next_token = 3; // Token to retrieve the next page of results, absent if there are no more results.
}

// Request to get data (as in plural of datum)
message ReadDataRequest {
  repeated bytes keys = 1;
  google.protobuf.FieldMask field_mask = 2; // Field mask to selectively return fields in the response.
}

// An evenlope that holds a datum for any of the compatible chains
message AnyChainDatum {
  bytes native_bytes = 1; // Original bytes as defined by the chain
  bytes key = 2;
  oneof parsed_state {
    utxorpc.v1beta.cardano.PlutusData cardano = 3; // A cardano UTxO
  }
}

// Response containing data (as in plural of datum)
message ReadDataResponse {
  repeated AnyChainDatum values = 1; // The value of each datum.
  ChainPoint ledger_tip = 2; // The chain point that represent the ledger current position.
}

// Request to get a transaction by hash
message ReadTxRequest {
  bytes hash = 1; // The hash of the transaction.
  google.protobuf.FieldMask field_mask = 2; // Field mask to selectively return fields in the response.
}

// Represents a transaction from any supported blockchain.
message AnyChainTx {
  bytes native_bytes = 1; // Original bytes as defined by the chain
  oneof chain {
    utxorpc.v1beta.cardano.Tx cardano = 2; // A Cardano transaction.
  }
  ChainPoint block_ref = 3; // The chain point that represents the block this transaction belongs to.
}

// Response containing the transaction associated with the requested hash.
message ReadTxResponse {
  AnyChainTx tx = 1; // The transaction.
  ChainPoint ledger_tip = 2; // The chain point that represent the ledger current position.
}

// Service definition for querying the state of the chain.
service QueryService {
  rpc ReadParams(ReadParamsRequest) returns (ReadParamsResponse); // Get overall chain state.
  rpc ReadUtxos(ReadUtxosRequest) returns (ReadUtxosResponse); // Read specific UTxOs by reference.
  rpc SearchUtxos(SearchUtxosRequest) returns (SearchUtxosResponse); // Search for UTxO based on a pattern.

  // TODO: decide if we want to expand the scope
  // rpc DumpUtxos(ReadUtxosRequest) returns (stream ReadUtxosResponse); // Dump all available utxos
  // rpc ReadAccount(ReadAccountRequest) returns (ReadAccountReponse); // Get state of a particular account
}
