import { execFile, spawnSync } from "node:child_process";
const COMMAND_TIMEOUT_MS = 10_000;
const LOGIN_TIMEOUT_MS = 5 * 60_000;
const AUTH_CACHE_TTL_MS = 30_000;
let cachedAuthStatus;
export async function checkClaudeCodeAuthStatus(cliPath) {
    const command = cliPath ?? "claude";
    const cacheKey = cliPath ?? "bundled-or-path";
    if (cachedAuthStatus?.key === cacheKey && Date.now() < cachedAuthStatus.expiresAt) {
        return cachedAuthStatus.status;
    }
    const status = checkWithCli(command);
    cachedAuthStatus = { key: cacheKey, status, expiresAt: Date.now() + AUTH_CACHE_TTL_MS };
    return status;
}
export function clearClaudeCodeAuthCache() {
    cachedAuthStatus = undefined;
}
export async function startClaudeCodeLogin(cliPath) {
    clearClaudeCodeAuthCache();
    try {
        const { stdout, stderr } = await runClaudeCodeCommand(cliPath ?? "claude", ["auth", "login"], LOGIN_TIMEOUT_MS);
        const output = [stdout, stderr].filter(Boolean).join("\n").trim();
        return {
            success: true,
            message: output || "Claude Code login completed.",
        };
    }
    catch (error) {
        return {
            success: false,
            message: extractCommandError(error) || "Claude Code login failed. Run 'claude auth login' on the host.",
        };
    }
}
export async function startClaudeCodeLogout(cliPath) {
    clearClaudeCodeAuthCache();
    try {
        const { stdout, stderr } = await runClaudeCodeCommand(cliPath ?? "claude", ["auth", "logout"], COMMAND_TIMEOUT_MS);
        const output = [stdout, stderr].filter(Boolean).join("\n").trim();
        return {
            success: true,
            message: output || "Logged out from Claude Code.",
        };
    }
    catch (error) {
        return {
            success: false,
            message: extractCommandError(error) || "Claude Code logout failed. Run 'claude auth logout' on the host.",
        };
    }
}
function checkWithCli(command) {
    const result = spawnSync(command, ["auth", "status"], {
        encoding: "utf8",
        timeout: COMMAND_TIMEOUT_MS,
        windowsHide: true,
        env: process.env,
    });
    const output = [result.stdout, result.stderr].filter(Boolean).join("\n").trim();
    if (!result.error && result.status === 0) {
        return {
            authenticated: true,
            method: "cli",
            detail: output || "Authenticated via Claude Code CLI.",
        };
    }
    if (result.error && result.error.code === "ENOENT") {
        return {
            authenticated: true,
            method: "cli",
            detail: "Claude Code CLI was not found on PATH; the Claude Agent SDK bundled runtime will perform its own auth check when a turn starts.",
        };
    }
    return {
        authenticated: false,
        method: "none",
        detail: output || result.error?.message || `Claude Code auth status failed with exit ${result.status ?? "unknown"}. Run "claude auth login" on the host.`,
    };
}
function runClaudeCodeCommand(command, args, timeout) {
    return new Promise((resolve, reject) => {
        execFile(command, args, {
            encoding: "utf8",
            timeout,
            windowsHide: true,
            env: { ...process.env },
            maxBuffer: 1024 * 1024,
        }, (error, stdout, stderr) => {
            if (error) {
                const enriched = error;
                enriched.stdout = typeof stdout === "string" ? stdout : "";
                enriched.stderr = typeof stderr === "string" ? stderr : "";
                reject(enriched);
                return;
            }
            resolve({
                stdout: typeof stdout === "string" ? stdout : "",
                stderr: typeof stderr === "string" ? stderr : "",
            });
        });
    });
}
function extractCommandError(error) {
    if (typeof error === "object" && error !== null) {
        const enriched = error;
        const stderr = enriched.stderr?.trim();
        if (stderr)
            return stderr;
        const stdout = enriched.stdout?.trim();
        if (stdout)
            return stdout;
        if (enriched.code === "ENOENT")
            return "Claude Code CLI not found. Install Claude Code or set CLAUDE_CODE_CLI_PATH.";
        if (enriched.signal)
            return `Command terminated with signal ${enriched.signal}.`;
        if (enriched.message)
            return enriched.message;
    }
    return error instanceof Error ? error.message : String(error);
}
