// Proto3 schema for running-process daemon IPC.
//
// Convention: RequestType enum values are chosen so that each value matches
// the field number of the corresponding payload message inside DaemonRequest
// and DaemonResponse.  For example, REGISTER = 10 corresponds to
// `RegisterRequest register = 10;` in DaemonRequest and
// `RegisterResponse register = 10;` in DaemonResponse.

syntax = "proto3";
package running_process.daemon.v1;

// ---------------------------------------------------------------------------
// Enums
// ---------------------------------------------------------------------------

enum RequestType {
  REQUEST_TYPE_UNSPECIFIED     = 0;
  REQUEST_TYPE_REGISTER        = 10;
  REQUEST_TYPE_UNREGISTER      = 11;
  REQUEST_TYPE_SPAWN_DAEMON    = 12;
  REQUEST_TYPE_LIST_ACTIVE     = 20;
  REQUEST_TYPE_LIST_BY_ORIGINATOR = 21;
  REQUEST_TYPE_GET_PROCESS_TREE = 22;
  REQUEST_TYPE_KILL_ZOMBIES    = 30;
  REQUEST_TYPE_KILL_TREE       = 31;
  REQUEST_TYPE_PING            = 40;
  REQUEST_TYPE_SHUTDOWN        = 41;
  REQUEST_TYPE_STATUS          = 42;
  // Service supervision (runpm) — Phase 1 ships stubs that respond OK.
  REQUEST_TYPE_SERVICE_START     = 50;
  REQUEST_TYPE_SERVICE_STOP      = 51;
  REQUEST_TYPE_SERVICE_RESTART   = 52;
  REQUEST_TYPE_SERVICE_DELETE    = 53;
  REQUEST_TYPE_SERVICE_LIST      = 54;
  REQUEST_TYPE_SERVICE_DESCRIBE  = 55;
  REQUEST_TYPE_SERVICE_LOGS      = 56;
  REQUEST_TYPE_SERVICE_FLUSH     = 57;
  REQUEST_TYPE_SERVICE_SAVE      = 58;
  REQUEST_TYPE_SERVICE_RESURRECT = 59;
}

enum StatusCode {
  STATUS_CODE_OK               = 0;
  STATUS_CODE_ERROR            = 1;
  STATUS_CODE_UNKNOWN_REQUEST  = 2;
  STATUS_CODE_INVALID_ARGUMENT = 3;
  STATUS_CODE_NOT_FOUND        = 4;
  STATUS_CODE_INTERNAL         = 5;
  STATUS_CODE_UNAVAILABLE      = 6;
  STATUS_CODE_VERSION_MISMATCH = 7;
  STATUS_CODE_RATE_LIMITED     = 8;
}

enum ProcessState {
  PROCESS_STATE_UNKNOWN = 0;
  PROCESS_STATE_ALIVE   = 1;
  PROCESS_STATE_DEAD    = 2;
  PROCESS_STATE_ZOMBIE  = 3;
}

// ---------------------------------------------------------------------------
// Envelope messages
// ---------------------------------------------------------------------------

message DaemonRequest {
  uint64      id               = 1;
  RequestType type             = 2;
  uint32      protocol_version = 3;
  string      client_name      = 4;

  // Payload fields — field numbers match RequestType enum values.
  RegisterRequest         register          = 10;
  UnregisterRequest       unregister        = 11;
  SpawnDaemonRequest      spawn_daemon      = 12;
  ListActiveRequest       list_active       = 20;
  ListByOriginatorRequest list_by_originator = 21;
  GetProcessTreeRequest   get_process_tree  = 22;
  KillZombiesRequest      kill_zombies      = 30;
  KillTreeRequest         kill_tree         = 31;
  PingRequest             ping              = 40;
  ShutdownRequest         shutdown          = 41;
  StatusRequest           status            = 42;
  ServiceStartRequest     service_start     = 50;
  ServiceStopRequest      service_stop      = 51;
  ServiceRestartRequest   service_restart   = 52;
  ServiceDeleteRequest    service_delete    = 53;
  ServiceListRequest      service_list      = 54;
  ServiceDescribeRequest  service_describe  = 55;
  ServiceLogsRequest      service_logs      = 56;
  ServiceFlushRequest     service_flush     = 57;
  ServiceSaveRequest      service_save      = 58;
  ServiceResurrectRequest service_resurrect = 59;
}

message DaemonResponse {
  uint64     request_id = 1;
  StatusCode code       = 2;
  string     message    = 3;

  // Payload fields — field numbers match RequestType enum values.
  RegisterResponse         register          = 10;
  UnregisterResponse       unregister        = 11;
  SpawnDaemonResponse      spawn_daemon      = 12;
  ListActiveResponse       list_active       = 20;
  ListByOriginatorResponse list_by_originator = 21;
  GetProcessTreeResponse   get_process_tree  = 22;
  KillZombiesResponse      kill_zombies      = 30;
  KillTreeResponse         kill_tree         = 31;
  PingResponse             ping              = 40;
  ShutdownResponse         shutdown          = 41;
  StatusResponse           status            = 42;
  ServiceStartResponse     service_start     = 50;
  ServiceStopResponse      service_stop      = 51;
  ServiceRestartResponse   service_restart   = 52;
  ServiceDeleteResponse    service_delete    = 53;
  ServiceListResponse      service_list      = 54;
  ServiceDescribeResponse  service_describe  = 55;
  ServiceLogsResponse      service_logs      = 56;
  ServiceFlushResponse     service_flush     = 57;
  ServiceSaveResponse      service_save      = 58;
  ServiceResurrectResponse service_resurrect = 59;
}

// ---------------------------------------------------------------------------
// Payload messages
// ---------------------------------------------------------------------------

message RegisterRequest {
  uint32 pid        = 1;
  double created_at = 2;
  string kind       = 3;
  string command    = 4;
  string cwd        = 5;
  string originator = 6;
  string containment = 7;
}

message RegisterResponse {}

message UnregisterRequest {
  uint32 pid = 1;
}

message UnregisterResponse {}

message SpawnDaemonRequest {
  string command = 1;
  string cwd = 2;
  map<string, string> env = 3;
  string originator = 4;
}

message SpawnDaemonResponse {
  uint32 pid = 1;
  double created_at = 2;
  string command = 3;
  string cwd = 4;
  string originator = 5;
  string containment = 6;
}

message ListActiveRequest {}

message ListActiveResponse {
  repeated TrackedProcess processes = 1;
}

message ListByOriginatorRequest {
  string tool = 1;
}

message ListByOriginatorResponse {
  repeated TrackedProcess processes = 1;
}

message GetProcessTreeRequest {
  uint32 pid = 1;
}

message GetProcessTreeResponse {
  string tree_display = 1;
}

message KillZombiesRequest {
  bool dry_run = 1;
}

message KillZombiesResponse {
  repeated ZombieReport zombies = 1;
}

message ZombieReport {
  uint32 pid     = 1;
  string command = 2;
  string reason  = 3;
  bool   killed  = 4;
}

message KillTreeRequest {
  uint32 pid             = 1;
  double timeout_seconds = 2;
}

message KillTreeResponse {
  uint32 processes_killed = 1;
}

message PingRequest {}

message PingResponse {
  int64 server_time_ms = 1;
}

message ShutdownRequest {
  bool   graceful        = 1;
  double timeout_seconds = 2;
}

message ShutdownResponse {}

message StatusRequest {}

message StatusResponse {
  string version                = 1;
  uint64 uptime_seconds         = 2;
  uint32 tracked_process_count  = 3;
  uint32 active_connections     = 4;
  string socket_path            = 5;
  string db_path                = 6;
  string scope                  = 7;
  string scope_hash             = 8;
  string scope_cwd              = 9;
}

message TrackedProcess {
  uint32       pid              = 1;
  double       created_at       = 2;
  string       kind             = 3;
  string       command          = 4;
  string       cwd              = 5;
  string       originator       = 6;
  string       containment      = 7;
  double       registered_at    = 8;
  double       uptime_seconds   = 9;
  bool         parent_alive     = 10;
  ProcessState state            = 11;
  double       last_validated_at = 12;
}

// ---------------------------------------------------------------------------
// Service supervision (runpm) — Phase 1
//
// All handlers in Phase 1 return STATUS_CODE_OK with empty/default payloads.
// Real lifecycle, restart policy, and persistence land in Phase 2.
// ---------------------------------------------------------------------------

message ServiceConfig {
  string              name           = 1;
  repeated string     cmd            = 2;
  string              cwd            = 3;
  map<string, string> env            = 4;
  bool                autorestart    = 5;
  uint32              max_restarts   = 6;
  uint32              restart_delay_ms = 7;
  uint32              kill_timeout_ms  = 8;
  uint32              min_uptime_ms    = 9;
}

message ServiceState {
  string         name             = 1;
  uint32         id               = 2;
  string         status           = 3;  // "online" | "stopped" | "errored" | "starting"
  uint32         pid              = 4;
  uint32         restart_count    = 5;
  double         last_started_at  = 6;
  double         last_exited_at   = 7;
  int32          last_exit_code   = 8;
  ServiceConfig  config           = 9;
}

message ServiceStartRequest {
  ServiceConfig config = 1;
}
message ServiceStartResponse {
  ServiceState service = 1;
}

message ServiceStopRequest {
  string target = 1;  // name | id | "all"
}
message ServiceStopResponse {
  uint32 stopped_count = 1;
}

message ServiceRestartRequest {
  string target = 1;
}
message ServiceRestartResponse {
  uint32 restarted_count = 1;
}

message ServiceDeleteRequest {
  string target = 1;
}
message ServiceDeleteResponse {
  uint32 deleted_count = 1;
}

message ServiceListRequest {}
message ServiceListResponse {
  repeated ServiceState services = 1;
}

message ServiceDescribeRequest {
  string target = 1;
}
message ServiceDescribeResponse {
  ServiceState service = 1;
}

message ServiceLogsRequest {
  string target = 1;  // name | id | "" for all
  uint32 lines  = 2;
  bool   follow = 3;
}
message ServiceLogsResponse {
  string log_text = 1;
}

message ServiceFlushRequest {
  string target = 1;
}
message ServiceFlushResponse {
  uint32 flushed_count = 1;
}

message ServiceSaveRequest {}
message ServiceSaveResponse {
  string snapshot_path = 1;
  uint32 service_count = 2;
}

message ServiceResurrectRequest {}
message ServiceResurrectResponse {
  uint32 restored_count = 1;
}
