"use strict";
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.resolveActiveProfile = exports.CodexAuthProfileResolutionError = void 0;
/**
 * Synchronous hot-path resolver for the active codex auth profile. <5ms typical.
 * Precedence: CCS_CODEX_PROFILE env → registry.default → null (legacy ~/.codex).
 * Legacy fallback is allowed only when no explicit CCS_CODEX_PROFILE was requested.
 */
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const yaml = __importStar(require("js-yaml"));
const codex_profile_paths_1 = require("./codex-profile-paths");
const config_manager_1 = require("../utils/config-manager");
const types_1 = require("./types");
const codex_profile_registry_1 = require("./codex-profile-registry");
class CodexAuthProfileResolutionError extends Error {
    constructor(message) {
        super(message);
        this.name = 'CodexAuthProfileResolutionError';
    }
}
exports.CodexAuthProfileResolutionError = CodexAuthProfileResolutionError;
function quoteDiagnosticValue(value) {
    const escaped = value
        .replace(/[\x00-\x1f\x7f]/g, (char) => `\\x${char.charCodeAt(0).toString(16).padStart(2, '0')}`)
        .replace(/'/g, "\\'");
    return `'${escaped.length > 96 ? `${escaped.slice(0, 96)}...` : escaped}'`;
}
function registryDisplayPath(registryPath) {
    const [source] = (0, config_manager_1.getCcsDirSource)();
    if (source === 'default') {
        return process.platform === 'win32'
            ? '%USERPROFILE%\\.ccs\\codex-profiles.yaml'
            : '~/.ccs/codex-profiles.yaml';
    }
    if (source === 'CCS_HOME' || source === 'scoped:CCS_HOME') {
        return '$CCS_HOME/.ccs/codex-profiles.yaml';
    }
    if (source === 'CCS_DIR' || source === 'scoped:CCS_DIR') {
        return '$CCS_DIR/codex-profiles.yaml';
    }
    return registryPath;
}
function resolutionFailure(message, envName, displayEnvName) {
    const prefix = envName ? `CCS_CODEX_PROFILE=${displayEnvName} is set but ` : '';
    throw new CodexAuthProfileResolutionError(`${prefix}${message}. Refusing to fall back to ~/.codex.`);
}
function assertValidProfileNameForResolution(name, envName, displayEnvName) {
    const nameError = (0, types_1.getCodexProfileNameError)(name);
    if (nameError) {
        resolutionFailure(`profile name ${quoteDiagnosticValue(name)} is invalid: ${nameError}`, envName, displayEnvName);
    }
}
function assertValidProfileEntry(name, profiles, envName, displayEnvName, displayRegistryPath) {
    assertValidProfileNameForResolution(name, envName, displayEnvName);
    const profile = profiles[name];
    if (!profile || typeof profile !== 'object' || Array.isArray(profile)) {
        resolutionFailure(`registry profile ${quoteDiagnosticValue(name)} at ${displayRegistryPath} is not a valid object`, envName, displayEnvName);
    }
    const type = profile.type;
    if (type !== 'codex') {
        resolutionFailure(`registry profile ${quoteDiagnosticValue(name)} at ${displayRegistryPath} is not a Codex profile`, envName, displayEnvName);
    }
}
/** @param env - Process env map; defaults to process.env. Injectable for tests. */
function resolveActiveProfile(env = process.env) {
    const registryPath = (0, codex_profile_paths_1.getCodexAuthRegistryPath)();
    const envName = (env.CCS_CODEX_PROFILE ?? '').trim();
    const displayEnvName = quoteDiagnosticValue(envName);
    const displayRegistryPath = registryDisplayPath(registryPath);
    // F4: silent fallback — no registry means no profiles, legacy mode
    if (!fs.existsSync(registryPath)) {
        if (envName) {
            throw new CodexAuthProfileResolutionError(`CCS_CODEX_PROFILE=${displayEnvName} is set but ${displayRegistryPath} does not exist. Refusing to fall back to ~/.codex.`);
        }
        return null;
    }
    let parsed;
    try {
        const raw = fs.readFileSync(registryPath, 'utf8');
        parsed = yaml.load(raw);
    }
    catch (err) {
        if (err instanceof CodexAuthProfileResolutionError)
            throw err;
        const msg = `registry YAML could not be parsed at ${displayRegistryPath}`;
        resolutionFailure(msg, envName, displayEnvName);
    }
    let registry;
    try {
        registry = (0, codex_profile_registry_1.validateCodexProfileRegistryData)(parsed);
    }
    catch (err) {
        const msg = err instanceof Error ? err.message : String(err);
        resolutionFailure(`registry at ${displayRegistryPath} is invalid: ${msg}`, envName, displayEnvName);
    }
    const profiles = registry.profiles;
    if (!profiles || typeof profiles !== 'object' || Array.isArray(profiles)) {
        resolutionFailure(`registry at ${displayRegistryPath} is missing a valid profiles map`, envName, displayEnvName);
    }
    for (const profileName of Object.keys(profiles)) {
        assertValidProfileEntry(profileName, profiles, envName, displayEnvName, displayRegistryPath);
    }
    // F2: explicit env override
    if (envName) {
        assertValidProfileNameForResolution(envName, envName, displayEnvName);
        if (!Object.prototype.hasOwnProperty.call(profiles, envName)) {
            throw new CodexAuthProfileResolutionError(`CCS_CODEX_PROFILE=${displayEnvName} not found in registry. Refusing to fall back to ~/.codex.`);
        }
        assertValidProfileEntry(envName, profiles, envName, displayEnvName, displayRegistryPath);
        return {
            name: envName,
            dir: path.resolve((0, codex_profile_paths_1.resolveCodexProfileDir)(envName)),
            source: 'env',
        };
    }
    // F3: registry default
    const defaultName = registry.default;
    if (defaultName !== null) {
        if (typeof defaultName !== 'string') {
            resolutionFailure(`registry default at ${displayRegistryPath} is not a valid profile name`, envName, displayEnvName);
        }
        assertValidProfileNameForResolution(defaultName, envName, displayEnvName);
        if (!Object.prototype.hasOwnProperty.call(profiles, defaultName)) {
            resolutionFailure(`registry default ${quoteDiagnosticValue(defaultName)} is missing from profiles map`, envName, displayEnvName);
        }
        assertValidProfileEntry(defaultName, profiles, envName, displayEnvName, displayRegistryPath);
        return {
            name: defaultName,
            dir: path.resolve((0, codex_profile_paths_1.resolveCodexProfileDir)(defaultName)),
            source: 'default',
        };
    }
    // F4: no profile configured
    return null;
}
exports.resolveActiveProfile = resolveActiveProfile;
//# sourceMappingURL=resolve-active-profile.js.map