"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.finalizeDockerKeyRotation = exports.renderDockerKeyRotationBanner = exports.getDockerKeyRotationStatus = exports.maskDockerApiKey = exports.getActiveDockerLegacyApiKeys = exports.isDockerLegacyKeyGraceActive = exports.addLegacyKeyGrace = exports.createDockerBootstrapState = exports.writeDockerBootstrapState = exports.readDockerBootstrapState = exports.shouldEnableDockerLegacyKeyAuth = exports.shouldRestoreDockerLegacyApiKey = exports.isLikelyDockerGeneratedApiKey = exports.parseDockerLegacyKeyGraceDays = exports.getDockerBootstrapStatePath = exports.DOCKER_ENABLE_LEGACY_KEY_AUTH_ENV = exports.DOCKER_RESTORE_LEGACY_KEY_ENV = exports.DOCKER_LEGACY_KEY_GRACE_ENV = exports.DEFAULT_DOCKER_LEGACY_KEY_GRACE_DAYS = exports.DOCKER_LEGACY_API_KEY = exports.DOCKER_BOOTSTRAP_STATE_FILENAME = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const config_loader_facade_1 = require("../config/config-loader-facade");
exports.DOCKER_BOOTSTRAP_STATE_FILENAME = '.docker-bootstrap-state.json';
exports.DOCKER_LEGACY_API_KEY = 'ccs-internal-managed';
exports.DEFAULT_DOCKER_LEGACY_KEY_GRACE_DAYS = 14;
exports.DOCKER_LEGACY_KEY_GRACE_ENV = 'CCS_DOCKER_LEGACY_KEY_GRACE_DAYS';
exports.DOCKER_RESTORE_LEGACY_KEY_ENV = 'CCS_DOCKER_RESTORE_LEGACY_API_KEY';
exports.DOCKER_ENABLE_LEGACY_KEY_AUTH_ENV = 'CCS_DOCKER_ENABLE_LEGACY_KEY_AUTH';
const DAY_MS = 24 * 60 * 60 * 1000;
const STATE_VERSION = 1;
function getDockerBootstrapStatePath() {
    return path.join((0, config_loader_facade_1.getCcsDir)(), 'cliproxy', exports.DOCKER_BOOTSTRAP_STATE_FILENAME);
}
exports.getDockerBootstrapStatePath = getDockerBootstrapStatePath;
function parseDockerLegacyKeyGraceDays(env = process.env) {
    const rawValue = env[exports.DOCKER_LEGACY_KEY_GRACE_ENV];
    if (rawValue === undefined || rawValue.trim() === '') {
        return exports.DEFAULT_DOCKER_LEGACY_KEY_GRACE_DAYS;
    }
    const parsed = Number(rawValue);
    if (!Number.isFinite(parsed) || parsed < 0) {
        return exports.DEFAULT_DOCKER_LEGACY_KEY_GRACE_DAYS;
    }
    return Math.floor(parsed);
}
exports.parseDockerLegacyKeyGraceDays = parseDockerLegacyKeyGraceDays;
function isLikelyDockerGeneratedApiKey(value) {
    return Boolean(value && /^[A-Za-z0-9_-]{43}$/.test(value));
}
exports.isLikelyDockerGeneratedApiKey = isLikelyDockerGeneratedApiKey;
function shouldRestoreDockerLegacyApiKey(env = process.env) {
    return env[exports.DOCKER_RESTORE_LEGACY_KEY_ENV] === '1';
}
exports.shouldRestoreDockerLegacyApiKey = shouldRestoreDockerLegacyApiKey;
function shouldEnableDockerLegacyKeyAuth(env = process.env) {
    return env[exports.DOCKER_ENABLE_LEGACY_KEY_AUTH_ENV] === '1';
}
exports.shouldEnableDockerLegacyKeyAuth = shouldEnableDockerLegacyKeyAuth;
function readDockerBootstrapState() {
    const statePath = getDockerBootstrapStatePath();
    if (!fs.existsSync(statePath)) {
        return { state: null, corrupted: false, path: statePath };
    }
    try {
        const parsed = JSON.parse(fs.readFileSync(statePath, 'utf8'));
        if (!parsed || parsed.version !== STATE_VERSION || typeof parsed.bootstrappedAt !== 'string') {
            return { state: null, corrupted: true, path: statePath };
        }
        return { state: parsed, corrupted: false, path: statePath };
    }
    catch {
        return { state: null, corrupted: true, path: statePath };
    }
}
exports.readDockerBootstrapState = readDockerBootstrapState;
function writeDockerBootstrapState(state) {
    const statePath = getDockerBootstrapStatePath();
    fs.mkdirSync(path.dirname(statePath), { recursive: true, mode: 0o700 });
    const tempPath = `${statePath}.${process.pid}.${Date.now()}.tmp`;
    fs.writeFileSync(tempPath, `${JSON.stringify(state, null, 2)}\n`, { mode: 0o600 });
    fs.renameSync(tempPath, statePath);
}
exports.writeDockerBootstrapState = writeDockerBootstrapState;
function createDockerBootstrapState(apiKey, now = new Date()) {
    return {
        version: STATE_VERSION,
        apiKey,
        bootstrappedAt: now.toISOString(),
    };
}
exports.createDockerBootstrapState = createDockerBootstrapState;
function addLegacyKeyGrace(state, replacementKey, now = new Date(), graceDays = parseDockerLegacyKeyGraceDays()) {
    return {
        ...state,
        apiKey: replacementKey,
        legacyKeyGrace: {
            legacyKey: exports.DOCKER_LEGACY_API_KEY,
            replacementKey,
            startedAt: now.toISOString(),
            expiresAt: new Date(now.getTime() + graceDays * DAY_MS).toISOString(),
        },
    };
}
exports.addLegacyKeyGrace = addLegacyKeyGrace;
function isDockerLegacyKeyGraceActive(state, now = new Date()) {
    const grace = state?.legacyKeyGrace;
    if (!grace || grace.finalizedAt) {
        return false;
    }
    const expiresAt = Date.parse(grace.expiresAt);
    return Number.isFinite(expiresAt) && expiresAt > now.getTime();
}
exports.isDockerLegacyKeyGraceActive = isDockerLegacyKeyGraceActive;
function getActiveDockerLegacyApiKeys(now = new Date()) {
    if (!shouldEnableDockerLegacyKeyAuth()) {
        return [];
    }
    const { state } = readDockerBootstrapState();
    if (!isDockerLegacyKeyGraceActive(state, now)) {
        return [];
    }
    return state?.legacyKeyGrace?.legacyKey ? [state.legacyKeyGrace.legacyKey] : [];
}
exports.getActiveDockerLegacyApiKeys = getActiveDockerLegacyApiKeys;
function maskDockerApiKey(apiKey) {
    if (!apiKey) {
        return undefined;
    }
    if (apiKey.length <= 8) {
        return '****';
    }
    return `${apiKey.slice(0, 4)}...${apiKey.slice(-4)}`;
}
exports.maskDockerApiKey = maskDockerApiKey;
function getDockerKeyRotationStatus(now = new Date()) {
    const config = (0, config_loader_facade_1.loadOrCreateUnifiedConfig)();
    const readResult = readDockerBootstrapState();
    const apiKey = config.cliproxy.auth?.api_key;
    return {
        apiKey,
        maskedApiKey: maskDockerApiKey(apiKey),
        statePath: readResult.path,
        stateCorrupted: readResult.corrupted,
        legacyGraceActive: isDockerLegacyKeyGraceActive(readResult.state, now),
        legacyGrace: readResult.state?.legacyKeyGrace,
    };
}
exports.getDockerKeyRotationStatus = getDockerKeyRotationStatus;
function renderDockerKeyRotationBanner(status = getDockerKeyRotationStatus()) {
    if (!status.legacyGraceActive || !status.legacyGrace) {
        return '';
    }
    const maskedReplacementKey = maskDockerApiKey(status.legacyGrace.replacementKey) ?? '(not configured)';
    return [
        '[!] Docker CLIProxy API key rotation grace period is active.',
        `[i] New CLIProxy API key: ${maskedReplacementKey}`,
        `[i] Legacy key ${status.legacyGrace.legacyKey} remains valid until ${status.legacyGrace.expiresAt}.`,
        '[i] Reveal the full key with `ccs docker show-key --full`.',
        '[i] Update existing clients, then run `ccs docker finalize-key-rotation`.',
    ].join('\n');
}
exports.renderDockerKeyRotationBanner = renderDockerKeyRotationBanner;
function finalizeDockerKeyRotation(now = new Date()) {
    const readResult = readDockerBootstrapState();
    const state = readResult.state ??
        createDockerBootstrapState((0, config_loader_facade_1.loadOrCreateUnifiedConfig)().cliproxy.auth?.api_key, now);
    writeDockerBootstrapState({
        ...state,
        legacyKeyGrace: state.legacyKeyGrace
            ? {
                ...state.legacyKeyGrace,
                finalizedAt: now.toISOString(),
                expiresAt: now.toISOString(),
            }
            : undefined,
    });
    return getDockerKeyRotationStatus(now);
}
exports.finalizeDockerKeyRotation = finalizeDockerKeyRotation;
//# sourceMappingURL=docker-key-rotation.js.map