syntax = "proto3";

package coda.runner.v1;

option java_package = "coda.runner.v1";
option java_outer_classname = "RunnerProto";

service RunnerService {
  // Bidirectional: server sends request + data responses,
  // runner sends status + data requests + result
  rpc ExecuteCode(stream ExecuteCodeMessage) returns (stream ExecuteCodeEvent);

  // Unary: enqueue datasource refresh to SQS, return ack
  rpc RefreshDataSource(RefreshRequest) returns (RefreshResponse);

  // Unary: poll refresh status
  rpc GetRefreshStatus(RefreshStatusRequest) returns (RefreshStatusResponse);
}

// --- ExecuteCode bidirectional streaming ---

message ExecuteCodeMessage {
  oneof message {
    ExecuteCodeRequest request = 1;
    DataResponse data_response = 2;
  }
}

message ExecuteCodeRequest {
  string request_id = 1;
  string code = 2;
  ToolPolicy tool_policy = 3;
  IsolateLimits isolate_limits = 4;
  BridgeLimits bridge_limits = 5;
  map<string, string> identity_context = 6;
}

message DataResponse {
  string request_id = 1;
  string data_request_id = 2;
  bytes data = 3;
  ErrorInfo error = 4;
}

message ExecuteCodeEvent {
  oneof event {
    StatusEvent status = 1;
    DataRequestEvent data_request = 2;
    ResultEvent result = 3;
    ErrorEvent error = 4;
  }
}

message StatusEvent {
  string request_id = 1;
  string stage = 2;
  string message = 3;
}

message DataRequestEvent {
  string request_id = 1;
  string data_request_id = 2;
  string method = 3;
  bytes params = 4;
}

message ResultEvent {
  string request_id = 1;
  bytes payload = 2;
  ExecutionStats stats = 3;
}

message ErrorEvent {
  string request_id = 1;
  string code = 2;
  string message = 3;
}

message ExecutionStats {
  int64 wall_ms = 1;
  int64 cpu_ms = 2;
  double heap_mb = 3;
  int32 data_request_count = 4;
  int64 data_bytes_received = 5;
}

// --- Policy and limits ---

message ToolPolicy {
  repeated string allowed_tools = 1;
  bool read_only = 2;
}

message IsolateLimits {
  int32 timeout_ms = 1;
  int32 max_code_bytes = 2;
}

message BridgeLimits {
  int32 max_data_requests = 1;
  int64 max_data_bytes = 2;
  int64 max_result_bytes = 3;
  int32 max_status_events = 4;
  int64 max_emit_bytes = 5;
}

// --- Refresh RPCs ---

message RefreshRequest {
  string datasource_id = 1;
  string triggered_by = 2;
  string request_id = 3;
}

message RefreshResponse {
  bool accepted = 1;
  string message = 2;
}

message RefreshStatusRequest {
  string datasource_id = 1;
}

message RefreshStatusResponse {
  string status = 1;
  string last_refreshed_at = 2;
  string error = 3;
  int64 row_count = 4;
  int64 byte_size = 5;
}

// --- Shared ---

message ErrorInfo {
  string code = 1;
  string message = 2;
}
