import type { GateEntry } from '@mosaicstack/macp';

/** Stage dispatch mode. */
export type StageDispatch = 'exec' | 'yolo' | 'pi';

/** Stage type — determines agent selection and gate requirements. */
export type StageType = 'research' | 'review' | 'coding' | 'deploy';

/**
 * Typed outcome for every gate and stage evaluation — closed set (SDLC-D-035).
 *
 * Only `passed` means "verified by a real implementation". `simulated` is
 * produced exclusively in explicit `--simulate` runs and is never satisfying.
 */
export type ForgeOutcome =
  | 'passed'
  | 'failed'
  | 'blocked'
  | 'error'
  | 'waiting-for-authority'
  | 'simulated'
  | 'not-applicable';

/** A gate that requires authority (human/board) sign-off; no mechanical command can satisfy it. */
export interface AuthorityGate {
  kind: 'authority';
  capability: string;
  reason: string;
}

/** A gate that requires a wired provider (e.g. an AI reviewer, CI pipeline) to evaluate. */
export interface ProviderGate {
  kind: 'provider';
  capability: string;
  reason: string;
}

/** Forge quality gate: a real command, an authority sign-off, or a provider-backed check. */
export type ForgeGate = string | GateEntry | AuthorityGate | ProviderGate;

/** Typed result of evaluating a single quality gate. */
export interface ForgeGateResult {
  gate: string;
  outcome: ForgeOutcome;
  reason: string;
  exitCode?: number;
  output?: string;
  timedOut?: boolean;
}

/** Typed result of a task/stage execution returned by a TaskExecutor. */
export interface ForgeTaskResult {
  task_id: string;
  outcome: ForgeOutcome;
  reason: string;
  completed_at: string;
  exit_code: number;
  gate_results: ForgeGateResult[];
}

/** Stage specification — defines a single pipeline stage. */
export interface StageSpec {
  number: string;
  title: string;
  dispatch: StageDispatch;
  type: StageType;
  gate: string;
  promptFile: string;
  qualityGates: ForgeGate[];
}

/** Brief classification. */
export type BriefClass = 'strategic' | 'technical' | 'hotfix';

/** How the brief class was determined. */
export type ClassSource = 'cli' | 'frontmatter' | 'auto';

/** Per-stage status within a run manifest. */
export interface StageStatus {
  status: 'pending' | 'in_progress' | ForgeOutcome;
  /** Why the stage reached its current (terminal) outcome, when applicable. */
  reason?: string;
  startedAt?: string;
  completedAt?: string;
  /** Typed per-gate results recorded alongside the stage outcome. */
  gateResults?: ForgeGateResult[];
}

/** Execution mode of a run. */
export type RunMode = 'normal' | 'simulated';

/** Run manifest — persisted to disk as manifest.json. */
export interface RunManifest {
  runId: string;
  brief: string;
  codebase: string;
  briefClass: BriefClass;
  classSource: ClassSource;
  forceBoard: boolean;
  /**
   * Execution mode. `simulated` runs stub execution; their results are typed
   * `simulated` and must never be read as verified success. Optional because
   * manifests written before this field existed default to `normal`.
   */
  mode?: RunMode;
  createdAt: string;
  updatedAt: string;
  currentStage: string;
  status:
    | 'in_progress'
    | 'completed'
    | 'failed'
    | 'interrupted'
    | 'rejected'
    | 'simulated'
    | 'waiting-for-authority';
  stages: Record<string, StageStatus>;
}

/** Task status for the executor. */
export type ForgeTaskStatus =
  | 'pending'
  | 'running'
  | 'completed'
  | 'failed'
  | 'gated'
  | 'escalated';

/** Task submitted to a TaskExecutor. */
export interface ForgeTask {
  id: string;
  title: string;
  description: string;
  status: ForgeTaskStatus;
  type: StageType;
  dispatch: StageDispatch;
  briefPath: string;
  resultPath: string;
  timeoutSeconds: number;
  qualityGates: ForgeGate[];
  worktree?: string;
  command?: string;
  dependsOn?: string[];
  dependsOnPolicy?: 'all' | 'any' | 'all_terminal';
  metadata: Record<string, unknown>;
}

/** Abstract task executor — decouples from packages/coord. */
export interface TaskExecutor {
  submitTask(task: ForgeTask): Promise<void>;
  waitForCompletion(taskId: string, timeoutMs: number): Promise<ForgeTaskResult>;
  getTaskStatus(taskId: string): Promise<ForgeTaskStatus>;
}

/** Board persona loaded from markdown. */
export interface BoardPersona {
  name: string;
  slug: string;
  description: string;
  path: string;
}

/** Board review result from a single persona. */
export interface PersonaReview {
  persona: string;
  verdict: 'approve' | 'reject' | 'conditional';
  confidence: number;
  concerns: string[];
  recommendations: string[];
  keyRisks: string[];
}

/** Board synthesis result merging all persona reviews. */
export interface BoardSynthesis extends PersonaReview {
  reviews: PersonaReview[];
}

/** Project-level Forge configuration (.forge/config.yaml). */
export interface ForgeConfig {
  board?: {
    additionalMembers?: string[];
    skipMembers?: string[];
  };
  specialists?: {
    alwaysInclude?: string[];
  };
}

/** Options for running a pipeline. */
export interface PipelineOptions {
  briefClass?: BriefClass;
  forceBoard?: boolean;
  codebase?: string;
  stages?: string[];
  skipTo?: string;
  dryRun?: boolean;
  /**
   * Real task executor. Required in normal mode: the pipeline fails closed
   * with FORGE_NO_EXECUTOR when it is absent.
   */
  executor?: TaskExecutor;
  /**
   * Explicit opt-in to simulated execution. Every stage and gate result is
   * typed `simulated` and is never satisfying.
   */
  simulate?: boolean;
}

/** Pipeline run result. */
export interface PipelineResult {
  runId: string;
  briefPath: string;
  projectRoot: string;
  runDir: string;
  taskIds: string[];
  stages: string[];
  manifest: RunManifest;
}
