"use strict";
/**
 * codex-auth remove command.
 * Deletes profile dir + registry entry.
 * Guards: refuses to remove the default when others exist (unless --force).
 * Best-effort warning if CCS_CODEX_PROFILE points to it.
 * --yes skips confirmation prompt.
 */
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.handleRemoveCodex = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const ui_1 = require("../../utils/ui");
const prompt_1 = require("../../utils/prompt");
const errors_1 = require("../../errors");
const exit_codes_1 = require("../../errors/exit-codes");
const codex_profile_paths_1 = require("../codex-profile-paths");
const codex_account_identity_1 = require("../codex-account-identity");
const types_1 = require("./types");
async function handleRemoveCodex(ctx, args) {
    await (0, ui_1.initUI)();
    const parsed = (0, types_1.parseArgs)(args);
    (0, types_1.rejectUnsupportedOptions)(parsed, 'ccsx auth remove <name> [--yes|-y] [--force]', {
        yes: true,
        force: true,
    });
    const { profileName, yes, force } = parsed;
    if (!profileName) {
        console.log('Usage: ccsx auth remove <name> [--yes|-y] [--force]');
        (0, errors_1.exitWithError)('Profile name required', exit_codes_1.ExitCode.PROFILE_ERROR);
        return;
    }
    const nameError = (0, types_1.getProfileNameError)(profileName);
    if (nameError) {
        (0, errors_1.exitWithError)(nameError, exit_codes_1.ExitCode.PROFILE_ERROR);
        return;
    }
    const { registry } = ctx;
    if (!registry.hasProfile(profileName)) {
        (0, errors_1.exitWithError)(`Profile not found: ${profileName}`, exit_codes_1.ExitCode.PROFILE_ERROR);
        return;
    }
    const allProfiles = registry.listProfiles();
    const isDefault = registry.getDefault() === profileName;
    // Default guard: refuse if others exist and no --force
    if (isDefault && allProfiles.length > 1 && !force) {
        const others = allProfiles.filter((n) => n !== profileName);
        console.log(`    Switch first: ccsx auth switch ${others[0]}`);
        console.log(`    Or override : ccsx auth remove ${profileName} --force`);
        (0, errors_1.exitWithError)('Cannot remove default profile', exit_codes_1.ExitCode.PROFILE_ERROR);
        return;
    }
    // Active-env warning (best-effort — can only see current shell)
    if (process.env.CCS_CODEX_PROFILE === profileName) {
        process.stderr.write(`[!] CCS_CODEX_PROFILE in this shell points to "${profileName}".\n`);
        process.stderr.write(`    After removal, codex sessions in this shell will fail until you\n`);
        const others = allProfiles.filter((n) => n !== profileName);
        if (others.length > 0) {
            process.stderr.write(`    run: eval "$(ccsx auth use ${others[0]})" or unset CCS_CODEX_PROFILE.\n`);
        }
        else {
            process.stderr.write(`    run: unset CCS_CODEX_PROFILE\n`);
        }
    }
    const profileDir = (0, codex_profile_paths_1.resolveCodexProfileDir)(profileName);
    const authJsonPath = path.join(profileDir, 'auth.json');
    const authExists = fs.existsSync(authJsonPath);
    const dirExists = fs.existsSync(profileDir);
    // Load cached email for impact summary
    const meta = registry.getProfile(profileName);
    const originalDefault = registry.getDefault();
    let emailStr = meta.email ?? null;
    if (!emailStr && authExists) {
        const identity = (0, codex_account_identity_1.decodeAccountIdentity)(authJsonPath);
        emailStr = identity.email ?? null;
    }
    // Ghost case: dir already gone
    if (!dirExists) {
        process.stderr.write(`[!] Profile dir was already missing; removing registry entry only.\n`);
        try {
            registry.removeProfile(profileName, { forceDefault: force });
        }
        catch (err) {
            const msg = err instanceof Error ? err.message : String(err);
            (0, errors_1.exitWithError)(`Profile registry update failed; profile dir was already missing.\n  ${msg}`, exit_codes_1.ExitCode.GENERAL_ERROR);
            return;
        }
        console.log((0, ui_1.ok)(`Profile removed: ${profileName}`));
        return;
    }
    // Impact summary
    console.log(`Profile "${profileName}" will be removed.`);
    console.log(`  Profile dir   : ${profileDir}`);
    console.log(`  auth.json     : ${authExists ? 'present (will be deleted)' : 'not found'}`);
    console.log(`  Email         : ${emailStr ?? '<unknown>'}`);
    console.log('');
    // Confirm unless --yes
    if (!yes) {
        const confirmed = await prompt_1.InteractivePrompt.confirm('Delete this profile?', {
            default: false,
        });
        if (!confirmed) {
            console.log((0, ui_1.info)('Cancelled.'));
            return;
        }
    }
    const stagedDeleteDir = `${profileDir}.deleting.${process.pid}.${Math.random()
        .toString(36)
        .slice(2)}`;
    const preservationDir = `${profileDir}.preserved.${process.pid}.${Math.random()
        .toString(36)
        .slice(2)}`;
    try {
        fs.renameSync(profileDir, stagedDeleteDir);
    }
    catch (err) {
        const e = err;
        if (e.code === 'EACCES') {
            (0, errors_1.exitWithError)('Permission denied', exit_codes_1.ExitCode.GENERAL_ERROR);
            return;
        }
        throw err;
    }
    try {
        fs.cpSync(stagedDeleteDir, preservationDir, { recursive: true, errorOnExist: true });
    }
    catch (err) {
        const restored = _restoreProfileDir(stagedDeleteDir, profileDir);
        _removePathBestEffort(preservationDir);
        const preservedPath = restored ? profileDir : stagedDeleteDir;
        const msg = err instanceof Error ? err.message : String(err);
        (0, errors_1.exitWithError)(`Profile data delete preparation failed; profile data was preserved at ${preservedPath}.\n  ${msg}`, exit_codes_1.ExitCode.GENERAL_ERROR);
        return;
    }
    try {
        registry.removeProfile(profileName, { forceDefault: force });
    }
    catch (err) {
        const restored = _restoreProfileDir(stagedDeleteDir, profileDir);
        _removePathBestEffort(preservationDir);
        const preservedPath = restored ? profileDir : stagedDeleteDir;
        const msg = err instanceof Error ? err.message : String(err);
        (0, errors_1.exitWithError)(`Profile registry update failed; profile data was preserved at ${preservedPath}.\n  ${msg}`, exit_codes_1.ExitCode.GENERAL_ERROR);
        return;
    }
    try {
        fs.rmSync(stagedDeleteDir, { recursive: true, force: true });
        fs.rmSync(preservationDir, { recursive: true, force: true });
    }
    catch (err) {
        const restoreSource = fs.existsSync(preservationDir) ? preservationDir : stagedDeleteDir;
        const restoredDir = _restoreProfileDir(restoreSource, profileDir);
        const restoredRegistry = _restoreRegistryEntry(registry, profileName, meta, originalDefault);
        if (restoredDir && restoreSource === preservationDir) {
            _removePathBestEffort(stagedDeleteDir);
        }
        const preservedPath = restoredDir ? profileDir : stagedDeleteDir;
        const msg = err instanceof Error ? err.message : String(err);
        const registryNote = restoredRegistry
            ? 'Profile registry entry was restored.'
            : 'Profile registry entry could not be restored automatically.';
        (0, errors_1.exitWithError)(`Profile data delete failed; profile data was preserved at ${preservedPath}. ${registryNote}\n  ${msg}`, exit_codes_1.ExitCode.GENERAL_ERROR);
        return;
    }
    console.log((0, ui_1.ok)(`Profile removed: ${profileName}`));
}
exports.handleRemoveCodex = handleRemoveCodex;
function _removePathBestEffort(targetPath) {
    try {
        fs.rmSync(targetPath, { recursive: true, force: true });
    }
    catch {
        // best-effort cleanup after data has already been preserved elsewhere
    }
}
function _restoreRegistryEntry(registry, profileName, meta, originalDefault) {
    try {
        if (registry.hasProfile(profileName)) {
            registry.updateProfile(profileName, meta);
        }
        else {
            registry.createProfile(profileName, meta);
        }
        if (originalDefault === profileName) {
            registry.setDefault(profileName);
        }
        return true;
    }
    catch {
        process.stderr.write(`[!] Profile data delete failed and automatic registry restore failed for "${profileName}".\n`);
        return false;
    }
}
function _restoreProfileDir(stagedDeleteDir, profileDir) {
    try {
        if (fs.existsSync(stagedDeleteDir) && !fs.existsSync(profileDir)) {
            fs.renameSync(stagedDeleteDir, profileDir);
            return true;
        }
        return fs.existsSync(profileDir);
    }
    catch {
        process.stderr.write(`[!] Registry update failed and automatic restore failed. Profile data remains at ${stagedDeleteDir}.\n`);
        return false;
    }
}
//# sourceMappingURL=remove-command.js.map