/**
 * Terminal State Types — Per-terminal state and content parts exposed on
 * `ahp-terminal:` channels.
 *
 * @module channels-terminal/state
 */

import type { URI } from '../common/state.js';

// ─── Terminal Types ──────────────────────────────────────────────────────────

/**
 * Lightweight terminal metadata exposed on the root state.
 *
 * @category Terminal Types
 */
export interface TerminalInfo {
  /** Terminal URI (subscribable for full terminal state) */
  resource: URI;
  /** Human-readable terminal title */
  title: string;
  /** Who currently holds this terminal */
  claim: TerminalClaim;
  /** Process exit code, if the terminal process has exited */
  exitCode?: number;
}

/**
 * Discriminant for terminal claim kinds.
 *
 * @category Terminal Types
 */
export const enum TerminalClaimKind {
  Client = 'client',
  Session = 'session',
}

/**
 * A terminal claimed by a connected client.
 *
 * @category Terminal Types
 */
export interface TerminalClientClaim {
  /** Discriminant */
  kind: TerminalClaimKind.Client;
  /** The `clientId` of the claiming client */
  clientId: string;
}

/**
 * A terminal claimed by a session, optionally scoped to a specific turn or tool call.
 *
 * @category Terminal Types
 */
export interface TerminalSessionClaim {
  /** Discriminant */
  kind: TerminalClaimKind.Session;
  /** Session URI that claimed the terminal */
  session: URI;
  /** Optional turn identifier within the session */
  turnId?: string;
  /** Optional tool call identifier within the turn */
  toolCallId?: string;
}

/**
 * Describes who currently holds a terminal. A terminal may be claimed by
 * either a connected client or a session (e.g. during a tool call).
 *
 * @category Terminal Types
 */
export type TerminalClaim = TerminalClientClaim | TerminalSessionClaim;

/**
 * Full state for a single terminal, loaded when a client subscribes to the terminal's URI.
 *
 * @category Terminal Types
 */
export interface TerminalState {
  /** Human-readable terminal title */
  title: string;
  /** Current working directory of the terminal process */
  cwd?: URI;
  /** Terminal width in columns */
  cols?: number;
  /** Terminal height in rows */
  rows?: number;
  /**
   * Typed content parts, replacing the flat `content: string`.
   *
   * Naive consumers that only need the raw VT stream can reconstruct it with:
   *   `content.map(p => p.type === 'command' ? p.output : p.value).join('')`
   *
   * Consumers that need command boundaries can filter by part type.
   */
  content: TerminalContentPart[];
  /** Process exit code, set when the terminal process exits */
  exitCode?: number;
  /** Who currently holds this terminal */
  claim: TerminalClaim;
  /**
   * Whether this terminal emits `terminal/commandExecuted` and
   * `terminal/commandFinished` actions and populates `command`-typed parts.
   *
   * Clients MUST check this flag before relying on command detection.
   * Do NOT use the presence of a `command` part as a feature flag — parts
   * are absent in the normal idle state.
   */
  supportsCommandDetection?: boolean;
}

// ─── Terminal Content Parts ──────────────────────────────────────────────────

/**
 * A content part within terminal output.
 *
 * @category Terminal Types
 */
export type TerminalContentPart =
  | TerminalUnclassifiedPart
  | TerminalCommandPart;

/**
 * Unstructured terminal output — content before, between, or after commands,
 * or from terminals that do not support command detection.
 *
 * @category Terminal Types
 */
export interface TerminalUnclassifiedPart {
  type: 'unclassified';
  /** Accumulated VT output. Appended to by `terminal/data` when no command is executing. */
  value: string;
}

/**
 * A single command: its command line and the output it produced.
 *
 * While `isComplete` is false the command is still executing; `output` grows
 * as `terminal/data` actions arrive. At `terminal/commandFinished` the part
 * is mutated in-place with `isComplete: true` and the completion metadata.
 *
 * @category Terminal Types
 */
export interface TerminalCommandPart {
  type: 'command';
  /**
   * Stable id matching the `commandId` on the corresponding
   * `terminal/commandExecuted` and `terminal/commandFinished` actions.
   */
  commandId: string;
  /** The command line submitted to the shell. */
  commandLine: string;
  /**
   * Accumulated VT output. Appended to by `terminal/data` while `isComplete`
   * is false. Shell integration escape sequences are stripped by the server.
   */
  output: string;
  /** Unix timestamp (ms) when execution started, as reported by the server. */
  timestamp: number;
  /** Whether the command has finished. */
  isComplete: boolean;
  /** Shell exit code. Set at completion. `undefined` if unknown. */
  exitCode?: number;
  /** Wall-clock duration in milliseconds. Set at completion. */
  durationMs?: number;
}
