// AirCoding V1.0.0 Alpha - IPC Contracts
// Implements: contracts §10 IPC — IpcDirection, IpcEnvelope, IpcKind, IpcMessage, ControlMessage, payloads
// Merges: workers.ts symbols per system-detailed-design.md §3, §8.2

import type {
  UUID,
  ISOTimeString,
  SessionID,
  AgentID,
} from './ids.js'
import type { RuntimeEvent } from './event.js'
import type { AirError } from './error.js'
import type { AgentRuntimeContext, ContextPack } from './runtime.js'

// Stub imports for types referenced from contracts §10 that don't exist yet
// These will be replaced with actual imports when the corresponding files are created
import type { TaskSpec } from './task.js'
import type { WorkerResult } from './worker-result.js'
import type { ToolResultEnvelope, ToolEvent, ToolExecutionContext } from './tool.js'

// §10.1 IPC Direction Types
export type IpcDirection = 'parent_to_worker' | 'worker_to_parent'

// §10.2 IPC Envelope
export interface IpcEnvelope<TPayload = unknown> {
  id: UUID
  direction: IpcDirection
  kind: IpcKind
  timestamp: ISOTimeString
  session_id: SessionID
  agent_id: AgentID
  correlation_id?: UUID
  protocol_version: number
  payload: TPayload
}

// §10.3 IPC Message Kinds
export type IpcKind =
  | 'control'
  | 'event'
  | 'log'
  | 'tool.call'
  | 'tool.result'
  | 'tool.stream'
  | 'worker.result'
  | 'worker.checkpoint'
  | 'protocol.error'

// §10.4 IPC Message Union
export type IpcMessage =
  | IpcEnvelope<ControlMessage>
  | IpcEnvelope<RuntimeEvent>
  | IpcEnvelope<LogPayload>
  | IpcEnvelope<ToolCallRequest>
  | IpcEnvelope<ToolCallResponse>
  | IpcEnvelope<ToolStreamPayload>
  | IpcEnvelope<WorkerResult>
  | IpcEnvelope<WorkerCheckpointPayload>
  | IpcEnvelope<ProtocolErrorPayload>

// §10.5 Direction-Typed Messages (per contracts §10)
// ParentToWorkerMessage covers: control, tool.result, tool.stream
export type ParentToWorkerMessage =
  | IpcEnvelope<ControlMessage>
  | IpcEnvelope<ToolCallResponse>
  | IpcEnvelope<ToolStreamPayload>

// WorkerToParentMessage covers: event, log, tool.call, worker.result, worker.checkpoint, protocol.error
export type WorkerToParentMessage =
  | IpcEnvelope<RuntimeEvent>
  | IpcEnvelope<LogPayload>
  | IpcEnvelope<ToolCallRequest>
  | IpcEnvelope<WorkerResult>
  | IpcEnvelope<WorkerCheckpointPayload>
  | IpcEnvelope<ProtocolErrorPayload>

// §10.6 Log Payload
export interface LogPayload {
  level: 'debug' | 'info' | 'warn' | 'error'
  message: string
  data?: unknown
}

// §10.7 Control Messages
export type ControlMessage =
  | AgentStartControlMessage
  | AgentCancelControlMessage
  | AgentPauseControlMessage
  | AgentResumeControlMessage
  | AgentExtendTimeoutControlMessage
  | WorkerReadyControlMessage

export interface AgentStartControlMessage {
  type: 'agent.start'
  version: 1
  task_spec: TaskSpec
  context_pack: ContextPack
  runtime: AgentRuntimeContext
}

export interface AgentCancelControlMessage {
  type: 'agent.cancel'
  reason: string
}

export interface AgentPauseControlMessage {
  type: 'agent.pause'
  reason: string
}

export interface AgentResumeControlMessage {
  type: 'agent.resume'
}

export interface AgentExtendTimeoutControlMessage {
  type: 'agent.extend_timeout'
  extra_ms: number
  reason: string
}

export interface WorkerReadyControlMessage {
  type: 'worker.ready'
  protocol_version: number
  worker_version: string
}

// §10.8 Tool Call Request (worker → parent)
export interface ToolCallRequest {
  tool_call_id: UUID
  tool_name: string
  input: unknown
  context: ToolExecutionContext
}

// §10.9 Tool Call Response (parent → worker)
export interface ToolCallResponse {
  tool_call_id: UUID
  result: ToolResultEnvelope
}

// §10.10 Tool Stream Payload
export interface ToolStreamPayload {
  tool_call_id: UUID
  event: ToolEvent
}

// §10.11 Worker Checkpoint Payload
export interface WorkerCheckpointPayload {
  checkpoint_id: UUID
  task_id: string // TaskID - using string to avoid import cycle
  data: unknown
}

// §10.12 Protocol Error Payload
export interface ProtocolErrorPayload {
  error: AirError
  received_message_id?: UUID
}

// ===== workers.ts symbols merged per system-detailed-design.md §3, §8.2 =====

/**
 * Worker role interface - implemented by worker child processes.
 * Each role (ExecutorRole, ReviewerRole, etc.) implements this interface.
 * The TResult type parameter specifies the result type for this role.
 */
export interface WorkerRole<TResult = unknown> {
  run(
    task_spec: TaskSpec,
    context_pack: ContextPack,
    runtime: WorkerRuntime
  ): Promise<WorkerResult<TResult>>
}

/**
 * Worker runtime - the IPC surface exposed to worker agents.
 * Workers use this to communicate with the parent process.
 * All filesystem/shell/network access goes through this interface.
 */
export interface WorkerRuntime {
  /**
   * Emit a runtime event to be ingested by the parent process.
   * Events flow through IPC → parent EventIngestor → EventStore/EventBus.
   */
  emit(event: RuntimeEvent): Promise<void>

  /**
   * Call a tool through the parent process.
   * The parent handles permission checking, execution, and event emission.
   * Returns the tool result envelope with status, output, and any errors.
   */
  call_tool<I, O>(
    name: string,
    input: I
  ): Promise<ToolResultEnvelope<O>>

  /**
   * Create a checkpoint with arbitrary data.
   * Useful for long-running tasks to save progress.
   * Emits a worker.checkpoint IPC message to the parent.
   */
  checkpoint(data: unknown): Promise<void>
}