"use strict";
/**
 * Auth Coordinator — Executor-level authentication handoff
 *
 * Extracted from executor/index.ts (Phase 06).
 * Handles:
 * - --logout early exit
 * - --import token early exit (Kiro only)
 * - --auth / forceAuth OAuth flow (single + composite providers)
 * - Antigravity responsibility gate (run and oauth contexts)
 * - isAuthenticated checks + automatic OAuth trigger
 * - Proactive token refresh (multi-provider for composite)
 * - lastUsedAt touch via touchDefaultAccount
 * - Preflight quota check
 * - Account safety guards (cross-provider isolation)
 * - First-run model configuration
 *
 * ORDERING (load-bearing — do not change):
 *   1. logout/import/forceAuth early exits
 *   2. Remote-proxy auth skip detection
 *   3. Antigravity gate (oauth context: remote+forceAuth | run context: else branch)
 *   4. OAuth check / trigger (single or composite)
 *   5. Token refresh
 *   6. lastUsedAt touch
 *   7. Preflight quota check
 *   8. Account safety guards
 *   9. First-run model configuration
 */
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
    if (mod && mod.__esModule) return mod;
    var result = {};
    if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
    __setModuleDefault(result, mod);
    return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ensureProviderSettingsFile = exports.ensureModelConfiguration = exports.runAccountSafetyGuards = exports.runPreflightQuotaCheck = exports.ensureProviderAuthentication = exports.runAntigravityGate = exports.resolveSkipLocalAuth = exports.handleImport = exports.handleLogout = void 0;
const ui_1 = require("../../utils/ui");
const auth_handler_1 = require("../auth/auth-handler");
const config_generator_1 = require("../config/config-generator");
const model_config_1 = require("../config/model-config");
const codex_plan_compatibility_1 = require("../ai-providers/codex-plan-compatibility");
const model_catalog_1 = require("../model-catalog");
const antigravity_responsibility_1 = require("../auth/antigravity-responsibility");
const retry_handler_1 = require("./retry-handler");
const account_resolution_1 = require("./account-resolution");
const quota_manager_1 = require("../quota/quota-manager");
// ── 1. Special early-exit auth flags (logout / import) ────────────────────────
/**
 * Handle --logout: clear auth and exit 0.
 * Returns true if early exit occurred (caller should return immediately).
 */
async function handleLogout(context) {
    const { provider, parsedFlags } = context;
    if (!parsedFlags.forceLogout)
        return false;
    const providerConfig = (0, config_generator_1.getProviderConfig)(provider);
    const { clearAuth } = await Promise.resolve().then(() => __importStar(require('../auth/auth-handler')));
    if (clearAuth(provider)) {
        console.log((0, ui_1.ok)(`Logged out from ${providerConfig.displayName}`));
    }
    else {
        console.log((0, ui_1.info)(`No authentication found for ${providerConfig.displayName}`));
    }
    process.exit(0);
}
exports.handleLogout = handleLogout;
/**
 * Handle --import: Kiro-only token import flow, exits when done.
 * Returns true if early exit occurred.
 */
async function handleImport(context) {
    const { provider, parsedFlags, verbose } = context;
    const { forceImport, forceAuth, forceLogout, kiroAuthMethod, kiroIDCStartUrl, kiroIDCRegion, kiroIDCFlow, setNickname, } = parsedFlags;
    if (!forceImport)
        return false;
    if (provider !== 'kiro') {
        console.error((0, ui_1.fail)('--import is only available for Kiro'));
        console.error(`    Run "ccs ${provider} --auth" to authenticate`);
        process.exit(1);
    }
    if (forceAuth) {
        console.error((0, ui_1.fail)('Cannot use --import with --auth'));
        console.error('    --import: Import existing token from Kiro IDE');
        console.error('    --auth: Trigger new OAuth flow in browser');
        process.exit(1);
    }
    if (forceLogout) {
        console.error((0, ui_1.fail)('Cannot use --import with --logout'));
        process.exit(1);
    }
    const { triggerOAuth } = await Promise.resolve().then(() => __importStar(require('../auth/auth-handler')));
    const authSuccess = await triggerOAuth(provider, {
        verbose,
        import: true,
        ...(kiroAuthMethod ? { kiroMethod: kiroAuthMethod } : {}),
        ...(kiroIDCStartUrl ? { kiroIDCStartUrl } : {}),
        ...(kiroIDCRegion ? { kiroIDCRegion } : {}),
        ...(kiroIDCFlow ? { kiroIDCFlow } : {}),
        ...(setNickname ? { nickname: setNickname } : {}),
    });
    if (!authSuccess) {
        console.error((0, ui_1.fail)('Failed to import Kiro token from IDE'));
        console.error('    Make sure you are logged into Kiro IDE first');
        process.exit(1);
    }
    process.exit(0);
}
exports.handleImport = handleImport;
// ── 2. Remote proxy auth skip ──────────────────────────────────────────────────
/**
 * Returns true when a remote proxy with an authToken is active —
 * local OAuth is not needed in this case.
 */
function resolveSkipLocalAuth(remoteAuthToken, useRemoteProxy) {
    return useRemoteProxy && !!remoteAuthToken?.trim();
}
exports.resolveSkipLocalAuth = resolveSkipLocalAuth;
// ── 3. Antigravity responsibility gate ────────────────────────────────────────
/**
 * Runs the Antigravity responsibility gate for the relevant code path.
 *
 * Two scenarios (must match original ordering in index.ts):
 *   A. provider=agy + forceAuth + skipLocalAuth → oauth-context gate; if refused, log and return
 *      (caller must return early — this function returns { earlyReturn: true })
 *   B. provider=agy + !forceAuth + (skipLocalAuth || !requiresAuthNow) → run-context gate;
 *      if refused, log and process.exit(1)
 *
 * Returns { earlyReturn: true } when the caller should return immediately (case A refused).
 */
async function runAntigravityGate(context, skipLocalAuth) {
    const { provider, parsedFlags } = context;
    const { forceAuth, acceptAgyRisk } = parsedFlags;
    if (provider !== 'agy')
        return { earlyReturn: false };
    const providerConfig = (0, config_generator_1.getProviderConfig)(provider);
    const requiresAuthNow = providerConfig.requiresOAuth && !(0, auth_handler_1.isAuthenticated)(provider);
    if (forceAuth && skipLocalAuth) {
        // Case A: remote proxy + forceAuth — gate in oauth context, skip local OAuth
        const acknowledged = await (0, antigravity_responsibility_1.ensureCliAntigravityResponsibility)({
            context: 'oauth',
            acceptedByFlag: acceptAgyRisk,
        });
        if (!acknowledged) {
            throw new Error(`Antigravity auth blocked. Re-run after completing confirmation or pass ${antigravity_responsibility_1.ANTIGRAVITY_ACCEPT_RISK_FLAGS[0]}.`);
        }
        console.error((0, ui_1.info)('Remote proxy mode is active; local OAuth flow is skipped in --auth mode.'));
        return { earlyReturn: true };
    }
    if (!forceAuth) {
        // Case B: run-context gate (only when auth not immediately required)
        if (skipLocalAuth || !requiresAuthNow) {
            const acknowledged = await (0, antigravity_responsibility_1.ensureCliAntigravityResponsibility)({
                context: 'run',
                acceptedByFlag: acceptAgyRisk,
            });
            if (!acknowledged) {
                console.error((0, ui_1.fail)(`Antigravity session blocked. Re-run after completing confirmation or pass ${antigravity_responsibility_1.ANTIGRAVITY_ACCEPT_RISK_FLAGS[0]}.`));
                process.exit(1);
            }
        }
    }
    return { earlyReturn: false };
}
exports.runAntigravityGate = runAntigravityGate;
// ── 4–6. OAuth check / trigger + token refresh + account touch ─────────────────
/**
 * Ensure provider(s) are authenticated; trigger OAuth if needed.
 * Handles both composite (multi-provider) and single-provider flows.
 * Also runs proactive token refresh and touches lastUsedAt.
 *
 * Only called when providerConfig.requiresOAuth && !skipLocalAuth.
 */
async function ensureProviderAuthentication(context) {
    const { provider, compositeProviders, parsedFlags, verbose, log } = context;
    const { forceAuth, addAccount, acceptAgyRisk, kiroAuthMethod, kiroIDCStartUrl, kiroIDCRegion, kiroIDCFlow, gitlabTokenLogin, gitlabBaseUrl, forceHeadless, setNickname, noIncognito, pasteCallback, portForward, } = parsedFlags;
    log(`Checking authentication for ${provider}`);
    // Multi-provider path (composite variants)
    if (compositeProviders.length > 0) {
        if (forceAuth) {
            const { triggerOAuth } = await Promise.resolve().then(() => __importStar(require('../auth/auth-handler')));
            const failures = [];
            for (const p of compositeProviders) {
                const authSuccess = await triggerOAuth(p, {
                    verbose,
                    add: addAccount,
                    ...(acceptAgyRisk ? { acceptAgyRisk: true } : {}),
                    ...(kiroAuthMethod && p === 'kiro' ? { kiroMethod: kiroAuthMethod } : {}),
                    ...(kiroIDCStartUrl && p === 'kiro' ? { kiroIDCStartUrl } : {}),
                    ...(kiroIDCRegion && p === 'kiro' ? { kiroIDCRegion } : {}),
                    ...(kiroIDCFlow && p === 'kiro' ? { kiroIDCFlow } : {}),
                    ...(gitlabTokenLogin && p === 'gitlab' ? { gitlabAuthMode: 'pat' } : {}),
                    ...(gitlabBaseUrl && p === 'gitlab' ? { gitlabBaseUrl } : {}),
                    ...(forceHeadless ? { headless: true } : {}),
                    ...(setNickname ? { nickname: setNickname } : {}),
                    ...(noIncognito ? { noIncognito: true } : {}),
                    ...(pasteCallback ? { pasteCallback: true } : {}),
                    ...(portForward ? { portForward: true } : {}),
                });
                if (!authSuccess) {
                    failures.push(p);
                }
            }
            if (failures.length > 0) {
                const succeeded = compositeProviders.filter((p) => !failures.includes(p));
                console.error((0, ui_1.fail)(`Auth failed for: ${failures.join(', ')}`));
                if (succeeded.length > 0) {
                    console.error((0, ui_1.info)(`Succeeded: ${succeeded.join(', ')}`));
                }
                process.exit(1);
            }
            process.exit(0);
        }
        // Check for unauthenticated providers
        const unauthenticatedProviders = [];
        for (const p of compositeProviders) {
            if (!(0, auth_handler_1.isAuthenticated)(p)) {
                unauthenticatedProviders.push(p);
            }
        }
        if (unauthenticatedProviders.length > 0) {
            console.error((0, ui_1.fail)('Composite variant requires authentication for multiple providers:'));
            for (const p of unauthenticatedProviders) {
                console.error(`    - ${p} (run "ccs ${p} --auth")`);
            }
            process.exit(1);
        }
    }
    else {
        // Single-provider path
        if (forceAuth || !(0, auth_handler_1.isAuthenticated)(provider)) {
            const { triggerOAuth } = await Promise.resolve().then(() => __importStar(require('../auth/auth-handler')));
            const providerConfig = (0, config_generator_1.getProviderConfig)(provider);
            const authSuccess = await triggerOAuth(provider, {
                verbose,
                add: addAccount,
                ...(acceptAgyRisk ? { acceptAgyRisk: true } : {}),
                ...(kiroAuthMethod ? { kiroMethod: kiroAuthMethod } : {}),
                ...(kiroIDCStartUrl ? { kiroIDCStartUrl } : {}),
                ...(kiroIDCRegion ? { kiroIDCRegion } : {}),
                ...(kiroIDCFlow ? { kiroIDCFlow } : {}),
                ...(gitlabTokenLogin ? { gitlabAuthMode: 'pat' } : {}),
                ...(gitlabBaseUrl ? { gitlabBaseUrl } : {}),
                ...(forceHeadless ? { headless: true } : {}),
                ...(setNickname ? { nickname: setNickname } : {}),
                ...(noIncognito ? { noIncognito: true } : {}),
                ...(pasteCallback ? { pasteCallback: true } : {}),
                ...(portForward ? { portForward: true } : {}),
            });
            if (!authSuccess) {
                throw new Error(`Authentication required for ${providerConfig.displayName}`);
            }
            if (forceAuth) {
                process.exit(0);
            }
        }
        else {
            log(`${provider} already authenticated`);
        }
    }
    // 3a. Proactive token refresh (multi-provider for composite)
    if (compositeProviders.length > 0) {
        for (const p of compositeProviders) {
            await (0, retry_handler_1.handleTokenExpiration)(p, verbose);
        }
    }
    else {
        await (0, retry_handler_1.handleTokenExpiration)(provider, verbose);
    }
    // 3a-1. Update lastUsedAt
    (0, account_resolution_1.touchDefaultAccount)(provider);
}
exports.ensureProviderAuthentication = ensureProviderAuthentication;
// ── 7. Preflight quota check ──────────────────────────────────────────────────
/**
 * Preflight quota check for providers with quota-based rotation.
 * Only runs when !skipLocalAuth.
 */
async function runPreflightQuotaCheck(provider, compositeProviders) {
    if (compositeProviders.length > 0) {
        for (const managedProvider of quota_manager_1.MANAGED_QUOTA_PROVIDERS) {
            if (compositeProviders.includes(managedProvider)) {
                await (0, retry_handler_1.handleQuotaCheck)(managedProvider);
            }
        }
    }
    else {
        await (0, retry_handler_1.handleQuotaCheck)(provider);
    }
}
exports.runPreflightQuotaCheck = runPreflightQuotaCheck;
// ── 8. Account safety guards ──────────────────────────────────────────────────
/**
 * Enforce cross-provider account isolation. Only runs when !skipLocalAuth.
 */
function runAccountSafetyGuards(provider, compositeProviders) {
    (0, account_resolution_1.applyAccountSafetyGuards)(provider, compositeProviders);
}
exports.runAccountSafetyGuards = runAccountSafetyGuards;
// ── 9. First-run model configuration ─────────────────────────────────────────
/**
 * Ensure provider model is configured on first run.
 * Skipped for composite variants and remote proxy mode.
 * Also reconciles Codex model for active plan.
 */
async function ensureModelConfiguration(provider, cfg, verbose) {
    if (!cfg.isComposite && (0, model_catalog_1.supportsModelConfig)(provider)) {
        await (0, model_config_1.configureProviderModel)(provider, false, cfg.customSettingsPath);
    }
    if (provider === 'codex' && !cfg.isComposite) {
        await (0, codex_plan_compatibility_1.reconcileCodexModelForActivePlan)({
            currentModel: (0, model_config_1.getCurrentModel)(provider, cfg.customSettingsPath),
            verbose,
        });
    }
}
exports.ensureModelConfiguration = ensureModelConfiguration;
// ── Ensure provider settings file ────────────────────────────────────────────
/**
 * Ensure the provider settings file exists.
 */
function ensureProviderSettingsFile(provider) {
    (0, config_generator_1.ensureProviderSettings)(provider);
}
exports.ensureProviderSettingsFile = ensureProviderSettingsFile;
//# sourceMappingURL=auth-coordinator.js.map