syntax = "proto3";

option go_package = "github.com/ehsaniara/joblet/internal/proto/gen/persist";

package joblet.persist;

// PersistService is an INTERNAL service for joblet-core ←→ persist IPC communication.
//
// ⚠️  DO NOT USE DIRECTLY - This service is for internal communication only via Unix socket.
//
// Public API: Use JobService.QueryLogs() and JobService.QueryMetrics()
//             These methods proxy to this internal service automatically.
//
// This service is provided by persist subprocess and communicates via Unix socket IPC.
service PersistService {
  // Health check - verify persist is running and responsive
  rpc Ping(PingRequest) returns (PingResponse);

  // Query logs for a job from disk storage
  rpc QueryLogs(QueryLogsRequest) returns (stream LogLine);

  // Query metrics for a job from disk storage
  rpc QueryMetrics(QueryMetricsRequest) returns (stream Metric);

  // Query exec events (eBPF telemetry) for a job
  rpc QueryExecEvents(QueryTelemetryRequest) returns (stream ExecEvent);

  // Query connect events (eBPF telemetry) for a job
  rpc QueryConnectEvents(QueryTelemetryRequest) returns (stream ConnectEvent);

  // Query mmap events (eBPF telemetry) for a job
  rpc QueryMmapEvents(QueryTelemetryRequest) returns (stream MmapEvent);

  // Query mprotect events (eBPF telemetry) for a job
  rpc QueryMprotectEvents(QueryTelemetryRequest) returns (stream MprotectEvent);

  // Query file events (eBPF telemetry) for a job
  rpc QueryFileEvents(QueryTelemetryRequest) returns (stream FileEvent);

  // Query accept events (eBPF telemetry) for a job
  rpc QueryAcceptEvents(QueryTelemetryRequest) returns (stream AcceptEvent);

  // Query socket data events (eBPF telemetry) for a job
  rpc QuerySocketDataEvents(QueryTelemetryRequest) returns (stream SocketDataEvent);

  // Delete all persisted data for a job (admin only)
  rpc DeleteJob(DeleteJobRequest) returns (DeleteJobResponse);
}

// PingRequest is a health check request (empty)
message PingRequest {}

// PingResponse indicates persist is healthy and responsive
message PingResponse {
  bool healthy = 1;
  int64 timestamp = 2;  // Unix nanoseconds when ping was processed
}

// QueryLogsRequest specifies parameters for log queries
message QueryLogsRequest {
  string job_uuid = 1;
  string node_id = 7;     // Node ID where the job ran (for CloudWatch log group lookup)

  // Stream filter
  StreamType stream = 2;  // STDOUT, STDERR, or both (UNSPECIFIED)

  // Time range (optional)
  int64 start_time = 3;  // Unix nanoseconds
  int64 end_time = 4;    // Unix nanoseconds

  // Pagination
  int32 limit = 5;       // Max lines to return (0 = all)
  int32 offset = 6;      // Skip lines
}

// QueryMetricsRequest specifies parameters for metrics queries
message QueryMetricsRequest {
  string job_uuid = 1;
  string node_id = 6;     // Node ID where the job ran (for CloudWatch log group lookup)

  // Time range (optional)
  int64 start_time = 2;  // Unix nanoseconds
  int64 end_time = 3;    // Unix nanoseconds

  // Pagination
  int32 limit = 4;       // Max samples to return (0 = all)
  int32 offset = 5;      // Skip samples
}

// LogLine represents a single log line from a job
message LogLine {
  string job_uuid = 1;
  StreamType stream = 2;     // stdout or stderr
  int64 timestamp = 3;       // Unix nanoseconds
  uint64 sequence = 4;       // Sequence number
  bytes content = 5;         // Log line content
}

// StreamType indicates stdout or stderr
enum StreamType {
  STREAM_TYPE_UNSPECIFIED = 0;
  STREAM_TYPE_STDOUT = 1;
  STREAM_TYPE_STDERR = 2;
}

// Metric represents a metrics sample from a job
message Metric {
  string job_uuid = 1;
  int64 timestamp = 2;       // Unix nanoseconds
  uint64 sequence = 3;       // Sequence number
  MetricData data = 4;       // Metric values
}

// MetricData contains the actual metric values
message MetricData {
  double cpu_usage = 1;           // CPU usage (0.0 - cores)
  int64 memory_usage = 2;         // Memory usage in bytes
  double gpu_usage = 3;           // GPU usage (0.0 - 1.0)
  DiskIO disk_io = 4;             // Disk I/O statistics
  NetworkIO network_io = 5;       // Network I/O statistics
}

// DiskIO represents disk I/O statistics
message DiskIO {
  int64 read_bytes = 1;
  int64 write_bytes = 2;
  int64 read_ops = 3;
  int64 write_ops = 4;
}

// NetworkIO represents network I/O statistics
message NetworkIO {
  int64 rx_bytes = 1;
  int64 tx_bytes = 2;
  int64 rx_packets = 3;
  int64 tx_packets = 4;
}

// DeleteJobRequest specifies the job to delete from persist storage
message DeleteJobRequest {
  string job_uuid = 1;
  string node_id = 2;     // Node ID where the job ran (for CloudWatch log group lookup)
}

// DeleteJobResponse indicates the result of the deletion
message DeleteJobResponse {
  bool success = 1;
  string message = 2;
}

// QueryTelemetryRequest specifies parameters for telemetry event queries
message QueryTelemetryRequest {
  string job_uuid = 1;
  string node_id = 6;     // Node ID where the job ran (for CloudWatch log group lookup)

  // Time range (optional)
  int64 start_time = 2;  // Unix nanoseconds
  int64 end_time = 3;    // Unix nanoseconds

  // Pagination
  int32 limit = 4;       // Max events to return (0 = all)
  int32 offset = 5;      // Skip events
}

// ExecEvent represents a process execution event from eBPF telematics
message ExecEvent {
  string job_uuid = 1;
  int64 timestamp = 2;       // Unix nanoseconds
  uint64 sequence = 3;       // Sequence number
  uint32 pid = 4;            // Process ID
  uint32 ppid = 5;           // Parent process ID
  uint32 uid = 6;            // User ID
  uint32 gid = 7;            // Group ID
  string comm = 8;           // Process command name (max 16 chars)
  string filename = 9;       // Full path to executable
  repeated string args = 10; // Command arguments
}

// ConnectEvent represents a network connection event from eBPF telematics
message ConnectEvent {
  string job_uuid = 1;
  int64 timestamp = 2;       // Unix nanoseconds
  uint64 sequence = 3;       // Sequence number
  uint32 pid = 4;            // Process ID
  string comm = 5;           // Process command name
  string src_addr = 6;       // Source IP address
  uint32 src_port = 7;       // Source port
  string dst_addr = 8;       // Destination IP address
  uint32 dst_port = 9;       // Destination port
  string protocol = 10;      // Protocol (TCP, UDP)
}

// MmapEvent represents a memory mapping event from eBPF telematics
message MmapEvent {
  string job_uuid = 1;
  int64 timestamp = 2;       // Unix nanoseconds
  uint64 sequence = 3;       // Sequence number
  uint32 pid = 4;            // Process ID
  string comm = 5;           // Process command name
  uint64 addr = 6;           // Memory address
  uint64 length = 7;         // Mapping length
  uint32 prot = 8;           // Protection flags
  uint32 flags = 9;          // Map flags
  string filename = 10;      // Mapped file (if file-backed)
}

// MprotectEvent represents a memory protection change event from eBPF telematics
message MprotectEvent {
  string job_uuid = 1;
  int64 timestamp = 2;       // Unix nanoseconds
  uint64 sequence = 3;       // Sequence number
  uint32 pid = 4;            // Process ID
  string comm = 5;           // Process command name
  uint64 addr = 6;           // Memory address
  uint64 length = 7;         // Region length
  uint32 prot = 8;           // New protection flags
}

// FileEvent represents a file operation event from eBPF telematics
message FileEvent {
  string job_uuid = 1;
  int64 timestamp = 2;       // Unix nanoseconds
  uint64 sequence = 3;       // Sequence number
  uint32 pid = 4;            // Process ID
  string comm = 5;           // Process command name
  string path = 6;           // File path
  string operation = 7;      // Operation type (open, read, write, etc.)
  int64 bytes = 8;           // Bytes read/written
}

// AcceptEvent represents an incoming network connection event from eBPF telematics
message AcceptEvent {
  string job_uuid = 1;
  int64 timestamp = 2;       // Unix nanoseconds
  uint64 sequence = 3;       // Sequence number
  uint32 pid = 4;            // Process ID
  string comm = 5;           // Process command name
  string src_addr = 6;       // Source IP address (remote client)
  uint32 src_port = 7;       // Source port
  string dst_addr = 8;       // Destination IP address (local server)
  uint32 dst_port = 9;       // Destination port
  string protocol = 10;      // Protocol (TCP)
}

// SocketDataEvent represents socket data transfer event from eBPF telematics
message SocketDataEvent {
  string job_uuid = 1;
  int64 timestamp = 2;       // Unix nanoseconds
  uint64 sequence = 3;       // Sequence number
  uint32 pid = 4;            // Process ID
  string comm = 5;           // Process command name
  string direction = 6;      // Direction (send, recv)
  string dst_addr = 7;       // Remote address
  uint32 dst_port = 8;       // Remote port
  int64 bytes = 9;           // Bytes transferred
  string protocol = 10;      // Protocol (TCP, UDP)
}
