syntax = "proto3";
package scada;

// ============================================================
// Service Definition
// ============================================================

service ScadaService {
  rpc Connect(ConnectRequest) returns (ConnectResponse);
  rpc Disconnect(DisconnectRequest) returns (DisconnectResponse);
  rpc GetConnectionState(GetConnectionStateRequest) returns (GetConnectionStateResponse);
  rpc Read(ReadRequest) returns (ReadResponse);
  rpc ReadBatch(ReadBatchRequest) returns (ReadBatchResponse);
  rpc Write(WriteRequest) returns (WriteResponse);
  rpc WriteBatch(WriteBatchRequest) returns (WriteBatchResponse);
  rpc WriteBatchAndWait(WriteBatchAndWaitRequest) returns (WriteBatchAndWaitResponse);
  rpc Subscribe(SubscribeRequest) returns (stream VtqMessage);
  rpc CheckApiKey(CheckApiKeyRequest) returns (CheckApiKeyResponse);
}

// ============================================================
// Typed Value System
// ============================================================

message TypedValue {
  oneof value {
    bool       bool_value     = 1;
    int32      int32_value    = 2;
    int64      int64_value    = 3;
    float      float_value    = 4;
    double     double_value   = 5;
    string     string_value   = 6;
    bytes      bytes_value    = 7;
    int64      datetime_value = 8;   // UTC DateTime.Ticks (100ns intervals since 0001-01-01)
    ArrayValue array_value    = 9;
  }
}

message ArrayValue {
  oneof values {
    BoolArray     bool_values     = 1;
    Int32Array    int32_values    = 2;
    Int64Array    int64_values    = 3;
    FloatArray    float_values    = 4;
    DoubleArray   double_values   = 5;
    StringArray   string_values   = 6;
    DatetimeArray datetime_values = 7;   // UTC DateTime.Ticks arrays
  }
}

message BoolArray     { repeated bool   values = 1; }
message Int32Array    { repeated int32  values = 1; }
message Int64Array    { repeated int64  values = 1; }
message FloatArray    { repeated float  values = 1; }
message DoubleArray   { repeated double values = 1; }
message StringArray   { repeated string values = 1; }
message DatetimeArray { repeated int64  values = 1; }  // UTC DateTime.Ticks

// ============================================================
// OPC UA-Style Quality Codes
// ============================================================

message QualityCode {
  uint32 status_code   = 1;
  string symbolic_name = 2;
}

// ============================================================
// Connection Lifecycle
// ============================================================

message ConnectRequest {
  string client_id = 1;
  string api_key   = 2;
}

message ConnectResponse {
  bool   success    = 1;
  string message    = 2;
  string session_id = 3;
}

message DisconnectRequest {
  string session_id = 1;
}

message DisconnectResponse {
  bool   success = 1;
  string message = 2;
}

message GetConnectionStateRequest {
  string session_id = 1;
}

message GetConnectionStateResponse {
  bool   is_connected              = 1;
  string client_id                 = 2;
  int64  connected_since_utc_ticks = 3;
}

message CheckApiKeyRequest {
  string api_key = 1;
}

message CheckApiKeyResponse {
  bool   is_valid = 1;
  string message  = 2;
}

// ============================================================
// Value-Timestamp-Quality
// ============================================================

message VtqMessage {
  string      tag                 = 1;
  TypedValue  value               = 2;
  int64       timestamp_utc_ticks = 3;
  QualityCode quality             = 4;
}

// ============================================================
// Read Operations
// ============================================================

message ReadRequest {
  string session_id = 1;
  string tag        = 2;
}

message ReadResponse {
  bool       success = 1;
  string     message = 2;
  VtqMessage vtq     = 3;
}

message ReadBatchRequest {
  string          session_id = 1;
  repeated string tags       = 2;
}

message ReadBatchResponse {
  bool                 success = 1;
  string               message = 2;
  repeated VtqMessage  vtqs    = 3;
}

// ============================================================
// Write Operations
// ============================================================

message WriteRequest {
  string     session_id = 1;
  string     tag        = 2;
  TypedValue value      = 3;
}

message WriteResponse {
  bool   success = 1;
  string message = 2;
}

message WriteItem {
  string     tag   = 1;
  TypedValue value = 2;
}

message WriteResult {
  string tag     = 1;
  bool   success = 2;
  string message = 3;
}

message WriteBatchRequest {
  string             session_id = 1;
  repeated WriteItem items      = 2;
}

message WriteBatchResponse {
  bool                 success = 1;
  string               message = 2;
  repeated WriteResult results = 3;
}

// ============================================================
// WriteBatchAndWait
// ============================================================

message WriteBatchAndWaitRequest {
  string             session_id       = 1;
  repeated WriteItem items            = 2;
  string             flag_tag         = 3;
  TypedValue         flag_value       = 4;
  int32              timeout_ms       = 5;
  int32              poll_interval_ms = 6;
}

message WriteBatchAndWaitResponse {
  bool                 success       = 1;
  string               message       = 2;
  repeated WriteResult write_results = 3;
  bool                 flag_reached  = 4;
  int32                elapsed_ms    = 5;
}

// ============================================================
// Subscription
// ============================================================

message SubscribeRequest {
  string          session_id  = 1;
  repeated string tags        = 2;
  int32           sampling_ms = 3;
}
