"use strict";
// src/cli/install/OAuthRunner.ts
// Wraps vendor OAuth CLIs (codex, gemini, grok) for the agent-profile auth phase.
//
// Each runner spawns the vendor CLI inheriting stdio so the operator can
// complete the browser login interactively. Returns ok/fail based on exit code
// + a post-login probe (`<cli> auth status` or equivalent) when available.
//
// Anthropic / Claude OAuth is INTENTIONALLY NOT IMPLEMENTED — explicit user
// policy as of May 2026: Claude credentials must be API key only.
Object.defineProperty(exports, "__esModule", { value: true });
exports.runOAuth = runOAuth;
const child_process_1 = require("child_process");
/**
 * Top-level OAuth dispatcher — picks the right runner per provider.
 * Throws PROVIDER_NOT_OAUTH if called for a provider without OAuth support.
 */
async function runOAuth(provider, opts = {}) {
    // Hard guard: explicit policy.
    if (provider === 'anthropic') {
        return {
            provider,
            ok: false,
            cli: '',
            detail: 'POLICY_BLOCK: Anthropic OAuth is not permitted — use API key only',
        };
    }
    switch (provider) {
        case 'openai-cli':
            return runCodexLogin(opts);
        case 'gemini-cli':
            return runGeminiLogin(opts);
        case 'xai':
            return runGrokLogin(opts);
        default:
            return {
                provider,
                ok: false,
                cli: '',
                detail: `PROVIDER_NOT_OAUTH: ${provider} does not support OAuth login`,
            };
    }
}
/**
 * Codex (OpenAI CLI) — interactive browser login. Reuses ChatGPT Plus/Pro
 * subscription via OAuth instead of consuming API credits.
 */
function runCodexLogin(opts) {
    const cli = opts.cliPath || 'codex';
    if (opts.dryRun) {
        return { provider: 'openai-cli', ok: true, cli, detail: 'dry-run' };
    }
    // codex login is interactive — needs inherited stdio so the browser prompt is visible.
    const loginRes = (0, child_process_1.spawnSync)(cli, ['login'], { stdio: 'inherit' });
    if (loginRes.status !== 0) {
        return {
            provider: 'openai-cli',
            ok: false,
            cli,
            detail: `codex login exited with code ${loginRes.status} (${loginRes.error?.message || 'no error message'})`,
        };
    }
    // Post-login probe — does `codex login status` confirm a session?
    try {
        const out = (0, child_process_1.execFileSync)(cli, ['login', 'status'], {
            encoding: 'utf-8',
            timeout: 8000,
        }).trim();
        if (/logged ?in|signed ?in|active/i.test(out)) {
            return { provider: 'openai-cli', ok: true, cli, detail: out.slice(0, 200) };
        }
        return {
            provider: 'openai-cli',
            ok: false,
            cli,
            detail: `codex login status did not confirm a session: ${out.slice(0, 200)}`,
        };
    }
    catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        // login succeeded but status probe failed — credit it as ok with a note.
        return { provider: 'openai-cli', ok: true, cli, detail: `login ok, status probe failed: ${msg}` };
    }
}
/**
 * Gemini CLI — device-auth OAuth via `gemini login`. Uses the operator's
 * Google account (not the GEMINI_API_KEY env var).
 */
function runGeminiLogin(opts) {
    const cli = opts.cliPath || 'gemini';
    if (opts.dryRun) {
        return { provider: 'gemini-cli', ok: true, cli, detail: 'dry-run' };
    }
    const loginRes = (0, child_process_1.spawnSync)(cli, ['login'], { stdio: 'inherit' });
    if (loginRes.status !== 0) {
        return {
            provider: 'gemini-cli',
            ok: false,
            cli,
            detail: `gemini login exited with code ${loginRes.status} (${loginRes.error?.message || 'no error message'})`,
        };
    }
    // Post-login probe
    try {
        const out = (0, child_process_1.execFileSync)(cli, ['login', 'status'], {
            encoding: 'utf-8',
            timeout: 8000,
        }).trim();
        if (/logged ?in|signed ?in|active|authenticated/i.test(out)) {
            return { provider: 'gemini-cli', ok: true, cli, detail: out.slice(0, 200) };
        }
        return {
            provider: 'gemini-cli',
            ok: false,
            cli,
            detail: `gemini login status did not confirm a session: ${out.slice(0, 200)}`,
        };
    }
    catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        return { provider: 'gemini-cli', ok: true, cli, detail: `login ok, status probe failed: ${msg}` };
    }
}
/**
 * xAI Grok — there's no first-party `grok` CLI yet, so this runs the
 * Grok device-auth flow when available, falling back to instructing the user
 * to obtain an API key from console.x.ai/team/default/api-keys.
 *
 * In practice this currently always reports "manual" — kept as a hook for
 * when xAI ships an official CLI.
 */
function runGrokLogin(opts) {
    const cli = opts.cliPath || 'grok';
    if (opts.dryRun) {
        return { provider: 'xai', ok: true, cli, detail: 'dry-run' };
    }
    // Probe whether a `grok` CLI exists with a `login` subcommand.
    try {
        const which = (0, child_process_1.spawnSync)(process.platform === 'win32' ? 'where' : 'which', [cli], {
            encoding: 'utf-8',
            timeout: 3000,
        });
        if (which.status !== 0) {
            return {
                provider: 'xai',
                ok: false,
                cli,
                detail: 'xAI device-auth OAuth requires the `grok` CLI which is not installed. Use API key instead (console.x.ai/team/default/api-keys).',
            };
        }
    }
    catch {
        return {
            provider: 'xai',
            ok: false,
            cli,
            detail: 'xAI device-auth OAuth could not be probed. Use API key instead (console.x.ai/team/default/api-keys).',
        };
    }
    const loginRes = (0, child_process_1.spawnSync)(cli, ['login'], { stdio: 'inherit' });
    if (loginRes.status !== 0) {
        return {
            provider: 'xai',
            ok: false,
            cli,
            detail: `grok login exited with code ${loginRes.status}`,
        };
    }
    return { provider: 'xai', ok: true, cli, detail: 'grok login succeeded (no status probe available)' };
}
