import type { AgentEventType, SessionStatus, PipeMode } from "@grackle-ai/common";

/** A single event emitted by an agent during execution. */
export interface AgentEvent {
  type: AgentEventType;
  timestamp: string;
  content: string;
  raw?: unknown;
}

/** Parameters for spawning a new agent session. */
export interface SpawnOptions {
  sessionId: string;
  prompt: string;
  model: string;
  maxTurns: number;
  branch?: string;
  workingDirectory?: string;
  useWorktrees?: boolean;
  systemContext?: string;
  workspaceId?: string;
  taskId?: string;
  /** MCP server configurations to pass to the agent SDK. */
  mcpServers?: Record<string, unknown>;
  /** SDK hook callbacks (e.g. Stop hooks). Only supported by the Claude Code runtime; other runtimes ignore this field. */
  hooks?: Record<string, unknown>;
  /** MCP broker connection details. Both url and token must be present together. */
  mcpBroker?: { url: string; token: string };
  /** Script source code for script personas (e.g. GenAIScript). */
  scriptContent?: string;
  /** Pipe mode for parent↔child IPC ("sync", "async", "detach", or undefined for no pipe). */
  pipe?: PipeMode;
}

/** Parameters for resuming an existing agent session. */
export interface ResumeOptions {
  sessionId: string;
  runtimeSessionId: string;
}

/** Options for creating an agent session (used by BaseAgentRuntime.createSession and BaseAgentSession constructor). */
export interface CreateSessionOptions {
  /** Session identifier. */
  id: string;
  /** Initial prompt text. */
  prompt: string;
  /** LLM model identifier. */
  model: string;
  /** Maximum turns (0 = unlimited). */
  maxTurns: number;
  /** Runtime session ID to resume (undefined for new sessions). */
  resumeSessionId?: string;
  /** Git branch name. */
  branch?: string;
  /** Working directory for the agent. */
  workingDirectory?: string;
  /** Whether to use git worktrees for isolation. */
  useWorktrees?: boolean;
  /** System context prepended to the prompt. */
  systemContext?: string;
  /** MCP server configurations to pass to the agent SDK. */
  mcpServers?: Record<string, unknown>;
  /** SDK hook callbacks (e.g. Stop hooks). Only supported by the Claude Code runtime; other runtimes ignore this field. */
  hooks?: Record<string, unknown>;
  /** MCP broker connection details. Both url and token must be present together. */
  mcpBroker?: { url: string; token: string };
}

/** Handle for an in-progress agent session with streaming, input, and kill capabilities. */
export interface AgentSession {
  id: string;
  runtimeName: string;
  runtimeSessionId: string;
  status: SessionStatus;
  /** Yield events as the agent runs. */
  stream(): AsyncIterable<AgentEvent>;
  /** Send user input to a session that is waiting for it. */
  sendInput(text: string): void;
  /** Forcefully terminate the session with an optional reason. */
  kill(reason?: string): void;
  /** Drain any buffered events that were not yet consumed by the stream. */
  drainBufferedEvents(): AgentEvent[];
}

/** Contract for pluggable agent runtime implementations (e.g. Claude Code, stub). */
export interface AgentRuntime {
  name: string;
  /** Create and start a new agent session. */
  spawn(opts: SpawnOptions): AgentSession;
  /** Resume a previously suspended session. */
  resume(opts: ResumeOptions): AgentSession;
}
