"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.createAuthProfile = createAuthProfile;
exports.hasSameAuthProfileDefinition = hasSameAuthProfileDefinition;
exports.createEmptyAuthProfilesFile = createEmptyAuthProfilesFile;
exports.createEmptyAuthProfileStateFile = createEmptyAuthProfileStateFile;
exports.appendAuthProfile = appendAuthProfile;
exports.replaceAuthProfiles = replaceAuthProfiles;
exports.normalizeAuthProfilesFile = normalizeAuthProfilesFile;
exports.removeAuthProfileById = removeAuthProfileById;
exports.removeAuthProfileStateById = removeAuthProfileStateById;
exports.buildAuthProfileState = buildAuthProfileState;
exports.replaceAuthProfileState = replaceAuthProfileState;
exports.getOrderedAuthProfiles = getOrderedAuthProfiles;
exports.getProviderAuthProfiles = getProviderAuthProfiles;
exports.normalizeAuthProfileOrders = normalizeAuthProfileOrders;
exports.applyProviderProfileOrder = applyProviderProfileOrder;
exports.nextAuthProfileOrder = nextAuthProfileOrder;
const paths_1 = require("../core/paths");
const format_1 = require("./format");
const kind_1 = require("./kind");
const model_1 = require("./model");
function createAuthProfile(input, homeDirectory) {
    const id = input.id ?? (0, format_1.createAuthProfileId)();
    const createdAt = input.createdAt ?? new Date().toISOString();
    const order = input.order ?? 1;
    switch (input.kind) {
        case "codex-home":
            return model_1.authProfileSchema.parse({
                id,
                createdAt,
                order,
                kind: input.kind,
                codexLoginMethod: input.codexLoginMethod ?? "browser",
                codexHomePath: input.codexHomePath ?? (0, paths_1.getCodexHomePath)(id, homeDirectory),
            });
        case "codex-env-var":
            return model_1.authProfileSchema.parse({
                id,
                createdAt,
                order,
                kind: input.kind,
                envVarName: input.envVarName,
            });
        case "claude-cli":
            return model_1.authProfileSchema.parse({
                id,
                createdAt,
                order,
                kind: input.kind,
                claudeConfigPath: input.claudeConfigPath ?? (0, paths_1.getClaudeConfigDirPath)(id, homeDirectory),
            });
        case "claude-api-key":
            return model_1.authProfileSchema.parse({
                id,
                createdAt,
                order,
                kind: input.kind,
            });
        case "claude-env-var":
            return model_1.authProfileSchema.parse({
                id,
                createdAt,
                order,
                kind: input.kind,
                envVarName: input.envVarName,
            });
    }
}
function hasSameAuthProfileDefinition(left, right) {
    if (left.kind !== right.kind) {
        return false;
    }
    switch (left.kind) {
        case "codex-home":
            return (right.kind === "codex-home" &&
                left.codexLoginMethod === right.codexLoginMethod &&
                left.codexHomePath === right.codexHomePath);
        case "claude-cli":
            return (right.kind === "claude-cli" &&
                left.claudeConfigPath === right.claudeConfigPath);
        case "codex-env-var":
            return (right.kind === "codex-env-var" && left.envVarName === right.envVarName);
        case "claude-api-key":
            return right.kind === "claude-api-key";
        case "claude-env-var":
            return (right.kind === "claude-env-var" && left.envVarName === right.envVarName);
    }
}
function createEmptyAuthProfilesFile() {
    return {
        version: model_1.AUTH_PROFILES_VERSION,
        profiles: [],
    };
}
function createEmptyAuthProfileStateFile() {
    return {
        version: model_1.AUTH_PROFILE_STATE_VERSION,
        states: [],
    };
}
function appendAuthProfile(profiles, profile) {
    return {
        version: profiles.version,
        profiles: normalizeAuthProfilesFile({
            version: profiles.version,
            profiles: [...profiles.profiles, profile],
        }).profiles,
    };
}
function replaceAuthProfiles(profiles, nextProfiles) {
    return normalizeAuthProfilesFile({
        version: profiles.version,
        profiles: [...nextProfiles],
    });
}
function normalizeAuthProfilesFile(file) {
    return {
        version: file.version,
        profiles: normalizeAuthProfileOrders(file.profiles),
    };
}
function removeAuthProfileById(profiles, profileId) {
    return normalizeAuthProfilesFile({
        version: profiles.version,
        profiles: profiles.profiles.filter((candidate) => candidate.id !== profileId),
    });
}
function removeAuthProfileStateById(state, profileId) {
    return {
        version: state.version,
        states: state.states.filter((candidate) => candidate.profileId !== profileId),
    };
}
function buildAuthProfileState(profileId, current, overrides, now = new Date()) {
    return model_1.authProfileStateSchema.parse({
        profileId,
        status: overrides?.status ?? current?.status ?? "ready",
        cooldownUntil: overrides?.cooldownUntil ?? current?.cooldownUntil ?? null,
        lastReason: overrides?.lastReason ?? current?.lastReason ?? null,
        updatedAt: overrides?.updatedAt ?? now.toISOString(),
    });
}
function replaceAuthProfileState(state, next) {
    return {
        version: state.version,
        states: [
            ...state.states.filter((candidate) => candidate.profileId !== next.profileId),
            next,
        ],
    };
}
function getOrderedAuthProfiles(profiles) {
    return [...profiles].sort(compareAuthProfiles);
}
function getProviderAuthProfiles(profiles, provider) {
    return getOrderedAuthProfiles(profiles).filter((profile) => (0, kind_1.getAuthProfileProvider)(profile) === provider);
}
function normalizeAuthProfileOrders(profiles) {
    const nextProfiles = getOrderedAuthProfiles(profiles);
    const providerOrder = new Map();
    return nextProfiles.map((profile) => {
        const provider = (0, kind_1.getAuthProfileProvider)(profile);
        const nextOrder = (providerOrder.get(provider) ?? 0) + 1;
        providerOrder.set(provider, nextOrder);
        if (profile.order === nextOrder) {
            return profile;
        }
        return {
            ...profile,
            order: nextOrder,
        };
    });
}
function applyProviderProfileOrder(profiles, provider, orderedProfileIds) {
    const providerProfiles = getProviderAuthProfiles(profiles, provider);
    const providerProfileIds = new Set(providerProfiles.map((profile) => profile.id));
    const seen = new Set();
    const nextOrder = [
        ...orderedProfileIds.filter((profileId) => providerProfileIds.has(profileId)),
        ...providerProfiles
            .map((profile) => profile.id)
            .filter((profileId) => !orderedProfileIds.includes(profileId)),
    ].filter((profileId) => {
        if (seen.has(profileId)) {
            return false;
        }
        seen.add(profileId);
        return true;
    });
    const orderByProfileId = new Map(nextOrder.map((profileId, index) => [profileId, index + 1]));
    return normalizeAuthProfileOrders(profiles.map((profile) => {
        if ((0, kind_1.getAuthProfileProvider)(profile) !== provider) {
            return profile;
        }
        const nextProfileOrder = orderByProfileId.get(profile.id);
        return nextProfileOrder === undefined
            ? profile
            : { ...profile, order: nextProfileOrder };
    }));
}
function nextAuthProfileOrder(profiles, provider) {
    return getProviderAuthProfiles(profiles, provider).length + 1;
}
function compareAuthProfiles(left, right) {
    return (compareProvider(left, right) ||
        left.order - right.order ||
        left.createdAt.localeCompare(right.createdAt) ||
        left.id.localeCompare(right.id));
}
function compareProvider(left, right) {
    return (getProviderRank((0, kind_1.getAuthProfileProvider)(left)) -
        getProviderRank((0, kind_1.getAuthProfileProvider)(right)));
}
function getProviderRank(provider) {
    return provider === "codex" ? 0 : 1;
}
