"use strict";
/**
 * Profile Mapper for CLIProxy Sync
 *
 * Transforms CCS settings-based profiles into CLIProxy ClaudeKey format.
 */
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.isProfileSyncable = exports.getSyncableProfileCount = exports.generateSyncPreview = exports.generateSyncPayload = exports.mapProfileToClaudeKey = exports.loadSyncableProfiles = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const helpers_1 = require("../../utils/helpers");
const profile_reader_1 = require("../../api/services/profile-reader");
const config_loader_facade_1 = require("../../config/config-loader-facade");
function resolveProfileSettingsPath(settingsPath) {
    const normalized = settingsPath.replace(/\\/g, '/');
    if (normalized.startsWith('~/.ccs/')) {
        return path.join((0, config_loader_facade_1.getCcsDir)(), normalized.slice('~/.ccs/'.length));
    }
    return (0, helpers_1.expandPath)(settingsPath);
}
/**
 * Load syncable API profiles from CCS config.
 * Filters to only configured profiles (with real API keys).
 */
function loadSyncableProfiles() {
    const { profiles } = (0, profile_reader_1.listApiProfiles)();
    const syncable = [];
    for (const profile of profiles) {
        // Skip unconfigured profiles
        if (!profile.isConfigured) {
            continue;
        }
        // Local CLIProxy sync writes Claude-compatible entries only.
        // Profiles pinned to non-claude targets are intentionally skipped.
        if (profile.target !== 'claude') {
            continue;
        }
        // Load settings.json for env vars
        const settingsPath = resolveProfileSettingsPath(profile.settingsPath);
        let env;
        try {
            if (fs.existsSync(settingsPath)) {
                const content = fs.readFileSync(settingsPath, 'utf8');
                const settings = JSON.parse(content);
                env = settings.env;
            }
        }
        catch {
            // Skip profiles with unreadable settings
            continue;
        }
        // Must have ANTHROPIC_AUTH_TOKEN
        const token = env?.ANTHROPIC_AUTH_TOKEN;
        if (!token || token.includes('YOUR_') || token.includes('your-')) {
            continue;
        }
        syncable.push({
            name: profile.name,
            settingsPath,
            isConfigured: true,
            env,
        });
    }
    return syncable;
}
exports.loadSyncableProfiles = loadSyncableProfiles;
/**
 * Sanitize profile name for YAML safety.
 * Replaces non-alphanumeric chars (except - and _) with hyphens.
 */
function sanitizeProfileName(name) {
    return name.replace(/[^a-zA-Z0-9-_]/g, '-');
}
/**
 * Map a single profile to ClaudeKey format.
 */
function mapProfileToClaudeKey(profile) {
    const env = profile.env;
    if (!env)
        return null;
    const apiKey = env.ANTHROPIC_AUTH_TOKEN;
    if (!apiKey)
        return null;
    const baseUrl = env.ANTHROPIC_BASE_URL;
    const modelName = env.ANTHROPIC_MODEL;
    // Generate prefix from profile name (e.g., "glm" -> "glm-")
    const sanitizedName = sanitizeProfileName(profile.name);
    if (!sanitizedName || sanitizedName === '') {
        return null; // Skip profiles with invalid names
    }
    // Skip if name is too long (>64 chars)
    if (sanitizedName.length > 64) {
        return null;
    }
    // Skip if name has no alphanumeric characters (e.g., only special chars -> "-----")
    if (!/[a-zA-Z0-9]/.test(sanitizedName)) {
        return null;
    }
    const prefix = `${sanitizedName}-`;
    const claudeKey = {
        'api-key': apiKey,
        prefix,
    };
    if (baseUrl) {
        claudeKey['base-url'] = baseUrl;
    }
    // Use model name directly from profile (no alias mapping)
    if (modelName) {
        claudeKey.models = [
            {
                name: modelName,
                alias: '',
            },
        ];
        // Append extra models from ANTHROPIC_EXTRA_MODELS env var (comma-separated).
        // Skip duplicates of the primary model and any repeated entries to keep
        // the synced CLIProxy `models` array clean.
        const extraModelsRaw = env.ANTHROPIC_EXTRA_MODELS;
        if (extraModelsRaw && extraModelsRaw.trim()) {
            const seen = new Set([modelName]);
            const extraModels = extraModelsRaw
                .split(',')
                .map((m) => m.trim())
                .filter((m) => m.length > 0);
            for (const extra of extraModels) {
                if (seen.has(extra)) {
                    continue;
                }
                seen.add(extra);
                claudeKey.models.push({
                    name: extra,
                    alias: '',
                });
            }
        }
    }
    return claudeKey;
}
exports.mapProfileToClaudeKey = mapProfileToClaudeKey;
/**
 * Generate sync payload from all configured profiles.
 * Returns array of ClaudeKey ready to push to remote CLIProxy.
 */
function generateSyncPayload() {
    const profiles = loadSyncableProfiles();
    const keys = [];
    for (const profile of profiles) {
        const key = mapProfileToClaudeKey(profile);
        if (key) {
            keys.push(key);
        }
    }
    return keys;
}
exports.generateSyncPayload = generateSyncPayload;
function generateSyncPreview() {
    const profiles = loadSyncableProfiles();
    const preview = [];
    for (const profile of profiles) {
        preview.push({
            name: profile.name,
            baseUrl: profile.env?.ANTHROPIC_BASE_URL,
            modelName: profile.env?.ANTHROPIC_MODEL,
        });
    }
    return preview;
}
exports.generateSyncPreview = generateSyncPreview;
/**
 * Get count of syncable profiles.
 */
function getSyncableProfileCount() {
    return loadSyncableProfiles().length;
}
exports.getSyncableProfileCount = getSyncableProfileCount;
/**
 * Check if profile is syncable (configured with valid API key).
 */
function isProfileSyncable(profileName) {
    return (0, profile_reader_1.isApiProfileConfigured)(profileName);
}
exports.isProfileSyncable = isProfileSyncable;
//# sourceMappingURL=profile-mapper.js.map