"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.removeVariantFromLegacyConfig = exports.removeVariantFromUnifiedConfig = exports.saveVariantLegacy = exports.saveVariantUnified = exports.saveCompositeVariantUnified = exports.listVariantsFromConfig = exports.getNextAvailablePort = exports.variantExistsInConfig = exports.VARIANT_PORT_MAX_OFFSET = exports.VARIANT_PORT_BASE = void 0;
const fs = __importStar(require("fs"));
const config_manager_1 = require("../../utils/config-manager");
const unified_config_types_1 = require("../../config/unified-config-types");
const config_generator_1 = require("../config/config-generator");
const config_loader_facade_1 = require("../../config/config-loader-facade");
exports.VARIANT_PORT_BASE = config_generator_1.CLIPROXY_DEFAULT_PORT + 1;
exports.VARIANT_PORT_MAX_OFFSET = 100;
function variantExistsInConfig(name) {
    try {
        if ((0, config_loader_facade_1.isUnifiedMode)()) {
            const config = (0, config_loader_facade_1.loadOrCreateUnifiedConfig)();
            return !!(config.cliproxy?.variants && name in config.cliproxy.variants);
        }
        const config = (0, config_loader_facade_1.loadConfigSafe)();
        return !!(config.cliproxy && name in config.cliproxy);
    }
    catch {
        return false;
    }
}
exports.variantExistsInConfig = variantExistsInConfig;
function getNextAvailablePort() {
    const variants = listVariantsFromConfig();
    const usedPorts = new Set();
    for (const name of Object.keys(variants)) {
        const port = variants[name].port;
        if (port)
            usedPorts.add(port);
    }
    // Find first available port in range
    for (let offset = 0; offset < exports.VARIANT_PORT_MAX_OFFSET; offset++) {
        const port = exports.VARIANT_PORT_BASE + offset;
        if (!usedPorts.has(port)) {
            return port;
        }
    }
    const variantCount = Object.keys(variants).length;
    throw new Error(`Port limit reached (${variantCount}/${exports.VARIANT_PORT_MAX_OFFSET} variants). ` +
        `Delete unused variants with 'ccs cliproxy remove <name>' to free ports.`);
}
exports.getNextAvailablePort = getNextAvailablePort;
function listVariantsFromConfig() {
    try {
        if ((0, config_loader_facade_1.isUnifiedMode)()) {
            const unifiedConfig = (0, config_loader_facade_1.loadOrCreateUnifiedConfig)();
            const variants = unifiedConfig.cliproxy?.variants || {};
            const result = {};
            for (const [name, variantConfig] of Object.entries(variants)) {
                try {
                    if ('type' in variantConfig && variantConfig.type === 'composite') {
                        const composite = variantConfig;
                        const tiers = composite.tiers;
                        if (!tiers || !tiers.opus || !tiers.sonnet || !tiers.haiku || !composite.default_tier) {
                            console.warn(`[!] Skipping malformed composite variant '${name}': missing required tier configuration`);
                            continue;
                        }
                        const defaultTierConfig = tiers[composite.default_tier];
                        if (!defaultTierConfig) {
                            console.warn(`[!] Skipping malformed composite variant '${name}': missing default tier '${composite.default_tier}'`);
                            continue;
                        }
                        const normalizedTiers = {
                            opus: tiers.opus,
                            sonnet: tiers.sonnet,
                            haiku: tiers.haiku,
                        };
                        const hasFallback = !!(normalizedTiers.opus.fallback ||
                            normalizedTiers.sonnet.fallback ||
                            normalizedTiers.haiku.fallback);
                        result[name] = {
                            provider: defaultTierConfig.provider,
                            settings: composite.settings,
                            port: composite.port,
                            target: composite.target || 'claude',
                            type: 'composite',
                            default_tier: composite.default_tier,
                            tiers: normalizedTiers,
                            hasFallback,
                        };
                    }
                    else {
                        const single = variantConfig;
                        result[name] = {
                            provider: single.provider,
                            settings: single.settings,
                            account: single.account,
                            port: single.port,
                            target: single.target || 'claude',
                        };
                    }
                }
                catch (error) {
                    console.warn(`[!] Skipping malformed variant '${name}': ${error.message || 'invalid config'}`);
                }
            }
            return result;
        }
        const config = (0, config_loader_facade_1.loadConfigSafe)();
        const variants = config.cliproxy || {};
        const result = {};
        for (const name of Object.keys(variants)) {
            const v = variants[name];
            result[name] = {
                provider: v.provider,
                settings: v.settings,
                account: v.account,
                port: v.port,
                target: v.target || 'claude',
            };
        }
        return result;
    }
    catch {
        return {};
    }
}
exports.listVariantsFromConfig = listVariantsFromConfig;
function saveCompositeVariantUnified(name, config) {
    (0, config_loader_facade_1.mutateConfig)((unifiedConfig) => {
        if (!unifiedConfig.cliproxy) {
            unifiedConfig.cliproxy = {
                oauth_accounts: {},
                providers: [...unified_config_types_1.CLIPROXY_SUPPORTED_PROVIDERS],
                variants: {},
            };
        }
        if (!unifiedConfig.cliproxy.variants) {
            unifiedConfig.cliproxy.variants = {};
        }
        unifiedConfig.cliproxy.variants[name] = config;
    });
}
exports.saveCompositeVariantUnified = saveCompositeVariantUnified;
function saveVariantUnified(name, provider, settingsPath, account, port, target = 'claude') {
    (0, config_loader_facade_1.mutateConfig)((config) => {
        if (!config.cliproxy) {
            config.cliproxy = {
                oauth_accounts: {},
                providers: [...unified_config_types_1.CLIPROXY_SUPPORTED_PROVIDERS],
                variants: {},
            };
        }
        if (!config.cliproxy.variants) {
            config.cliproxy.variants = {};
        }
        config.cliproxy.variants[name] = {
            provider,
            account,
            settings: settingsPath,
            port,
            ...(target !== 'claude' && { target }),
        };
    });
}
exports.saveVariantUnified = saveVariantUnified;
function saveVariantLegacy(name, provider, settingsPath, account, port, target = 'claude') {
    const configPath = (0, config_manager_1.getConfigPath)();
    let config;
    try {
        config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
    }
    catch {
        config = { profiles: {} };
    }
    if (!config.cliproxy) {
        config.cliproxy = {};
    }
    const variantConfig = {
        provider,
        settings: settingsPath,
    };
    if (account) {
        variantConfig.account = account;
    }
    if (port) {
        variantConfig.port = port;
    }
    if (target !== 'claude') {
        variantConfig.target = target;
    }
    config.cliproxy[name] = variantConfig;
    const tempPath = configPath + '.tmp';
    fs.writeFileSync(tempPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
    fs.renameSync(tempPath, configPath);
}
exports.saveVariantLegacy = saveVariantLegacy;
function removeVariantFromUnifiedConfig(name) {
    let removedVariant = null;
    (0, config_loader_facade_1.mutateConfig)((config) => {
        if (!config.cliproxy?.variants || !(name in config.cliproxy.variants)) {
            return;
        }
        removedVariant = config.cliproxy.variants[name];
        delete config.cliproxy.variants[name];
    });
    if (!removedVariant) {
        return null;
    }
    const composite = removedVariant;
    if (composite.type === 'composite') {
        return {
            provider: composite.tiers[composite.default_tier].provider,
            settings: composite.settings,
            port: composite.port,
            target: composite.target || 'claude',
            type: 'composite',
            default_tier: composite.default_tier,
            tiers: composite.tiers,
        };
    }
    const singleVariant = removedVariant;
    return {
        provider: singleVariant.provider,
        settings: singleVariant.settings,
        port: singleVariant.port,
        target: singleVariant.target || 'claude',
    };
}
exports.removeVariantFromUnifiedConfig = removeVariantFromUnifiedConfig;
function removeVariantFromLegacyConfig(name) {
    const configPath = (0, config_manager_1.getConfigPath)();
    let config;
    try {
        config = JSON.parse(fs.readFileSync(configPath, 'utf8'));
    }
    catch {
        return null;
    }
    if (!config.cliproxy || !(name in config.cliproxy)) {
        return null;
    }
    const variant = config.cliproxy[name];
    delete config.cliproxy[name];
    if (Object.keys(config.cliproxy).length === 0) {
        delete config.cliproxy;
    }
    const tempPath = configPath + '.tmp';
    fs.writeFileSync(tempPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
    fs.renameSync(tempPath, configPath);
    return variant;
}
exports.removeVariantFromLegacyConfig = removeVariantFromLegacyConfig;
//# sourceMappingURL=variant-config-adapter.js.map