export interface ProviderDef {
  name: string;
  label: string;
  transport: 'native' | 'acp' | 'pty';
  modelSource: 'llama-swap' | 'static' | 'probe';
  staticModels?: Array<{ id: string; label: string }>;
  /** Merge llama-swap models into probed list (OpenCode). */
  mergeLlamaSwap?: boolean;
}

/**
 * Model discovery rules (see provider-snapshot.ts):
 * - boocode: llama-swap only
 * - opencode: ACP probe + mergeLlamaSwap (prefixed llama-swap/* ids)
 * - qwen: ACP probe + merge ~/.qwen/settings.json; PTY fallback reads settings only
 * - goose: ACP probe only
 * - claude: static manifest models + thinking options
 */
export const PROVIDERS: ProviderDef[] = [
  {
    name: 'boocode',
    label: 'BooCoder',
    transport: 'native',
    modelSource: 'llama-swap',
  },
  {
    name: 'opencode',
    label: 'OpenCode',
    transport: 'acp',
    modelSource: 'probe',
    mergeLlamaSwap: true,
  },
  {
    name: 'goose',
    label: 'Goose',
    transport: 'acp',
    modelSource: 'probe',
  },
  {
    name: 'claude',
    // transport stays 'pty' — the DEFAULT dispatch path (one-shot `claude
    // --output-format stream-json`). claude-sdk-sessionstore #9 (Part 2) adds a warm
    // Claude-Agent-SDK backend (services/backends/claude-sdk.ts) routed ONLY when the
    // `CLAUDE_SDK_BACKEND` env flag is truthy AND the task is a chat tab; with the flag
    // off (production default) claude always uses this PTY path, so the transport label
    // is left unchanged. Flip the env var on a host (after a live smoke) to opt in.
    label: 'Claude Code',
    transport: 'pty',
    modelSource: 'static',
    // Passed verbatim to `claude --model <id>` (PTY dispatch). The CLI accepts a
    // latest-alias ('opus'/'sonnet'/'haiku') or a pinned full name
    // ('claude-opus-4-8'). Aliases never go stale; pinned IDs let you select an
    // exact version. Extend/replace per-install via data/coder-providers.json
    // (models / additionalModels) without a code change.
    staticModels: [
      { id: 'opus', label: 'Opus (latest)' },
      { id: 'claude-opus-4-8', label: 'Opus 4.8' },
      { id: 'sonnet', label: 'Sonnet (latest)' },
      { id: 'claude-sonnet-4-6', label: 'Sonnet 4.6' },
      { id: 'haiku', label: 'Haiku (latest)' },
      { id: 'claude-haiku-4-5-20251001', label: 'Haiku 4.5' },
    ],
  },
  {
    name: 'qwen',
    label: 'Qwen Code',
    transport: 'acp',
    modelSource: 'probe',
  },
];

export const PROVIDERS_BY_NAME = new Map(PROVIDERS.map((p) => [p.name, p]));

/** External agents probed on host (excludes native boocode). */
export const PROBED_AGENT_NAMES = PROVIDERS.filter((p) => p.name !== 'boocode').map((p) => p.name);
