/**
 * Codex MCP installer.
 *
 * Configures ShieldCortex as an MCP server for Codex by updating
 * ~/.codex/config.toml. Codex CLI and the Codex IDE extension share this
 * configuration, so one install covers both on the same machine.
 */
import fs from 'fs';
import os from 'os';
import path from 'path';
import { fileURLToPath } from 'url';
import { resolveMcpServerCommand } from './json-config.js';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const SERVER_NAME = 'shieldcortex-memory';
const MCP_ENTRY = path.resolve(__dirname, '..', 'index.js');
function escapeRegExp(value) {
    return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
}
function getCodexConfigPath() {
    return path.join(os.homedir(), '.codex', 'config.toml');
}
function readConfig() {
    const configPath = getCodexConfigPath();
    if (!fs.existsSync(configPath))
        return '';
    return fs.readFileSync(configPath, 'utf-8');
}
function writeConfig(content) {
    const configPath = getCodexConfigPath();
    fs.mkdirSync(path.dirname(configPath), { recursive: true });
    fs.writeFileSync(configPath, content.endsWith('\n') ? content : `${content}\n`, 'utf-8');
}
function escapeTomlString(value) {
    return value.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
}
function buildServerBlock() {
    // Prefer the absolute global binary (`which shieldcortex`); fall back to
    // `node <absolute dist/index.js>`. Never `npx -y` — see resolveMcpServerCommand
    // (the v4.11.1 fix: a dynamically-re-resolved command thrashes the editor's
    // MCP-config hash and resets the active session).
    const { command, args } = resolveMcpServerCommand(MCP_ENTRY);
    const argsToml = args.map((a) => `"${escapeTomlString(a)}"`).join(', ');
    return [
        `[mcp_servers.${SERVER_NAME}]`,
        `command = "${escapeTomlString(command)}"`,
        `args = [${argsToml}]`,
        '',
    ].join('\n');
}
function parseSections(content) {
    const lines = content.split(/\r?\n/);
    const sections = [];
    let current = { header: null, lines: [] };
    for (const line of lines) {
        const headerMatch = line.match(/^\[([^\]]+)\]\s*$/);
        if (headerMatch) {
            sections.push(current);
            current = { header: headerMatch[1], lines: [line] };
            continue;
        }
        current.lines.push(line);
    }
    sections.push(current);
    return sections;
}
function normalizeContent(content) {
    const trimmed = content.replace(/\n{3,}/g, '\n\n').trimEnd();
    return trimmed.length > 0 ? `${trimmed}\n` : '';
}
function hasServerBlock(content) {
    return new RegExp(`^\\[mcp_servers\\.${escapeRegExp(SERVER_NAME)}\\]\\r?$`, 'm').test(content);
}
function upsertServerBlock(content) {
    const block = buildServerBlock().trimEnd();
    const sections = parseSections(content);
    const output = [];
    let insertionIndex = -1;
    let found = false;
    for (const section of sections) {
        if (section.header === `mcp_servers.${SERVER_NAME}`) {
            if (insertionIndex === -1)
                insertionIndex = output.length;
            found = true;
            continue;
        }
        const rendered = section.lines.join('\n').trimEnd();
        if (rendered.length > 0)
            output.push(rendered);
    }
    if (insertionIndex === -1)
        insertionIndex = output.length;
    output.splice(insertionIndex, 0, block);
    const normalized = normalizeContent(output.join('\n\n'));
    if (found) {
        return { content: normalized, changed: normalized !== content };
    }
    return { content: normalized, changed: normalized !== content };
}
function removeServerBlock(content) {
    const sections = parseSections(content);
    const filtered = sections.filter((section) => section.header !== `mcp_servers.${SERVER_NAME}`);
    if (filtered.length === sections.length) {
        return { content, changed: false };
    }
    const normalized = normalizeContent(filtered
        .map((section) => section.lines.join('\n').trimEnd())
        .filter(Boolean)
        .join('\n\n'));
    return { content: normalized, changed: true };
}
export async function installCodex() {
    if (!fs.existsSync(MCP_ENTRY)) {
        console.error('ShieldCortex MCP entry point not found. Package may be corrupted.');
        console.error(`Expected: ${MCP_ENTRY}`);
        process.exit(1);
    }
    const existing = readConfig();
    const result = upsertServerBlock(existing);
    writeConfig(result.content);
    if (result.changed) {
        console.log(`✓ Codex — configured ShieldCortex in ${getCodexConfigPath()}`);
    }
    else {
        console.log('· Codex — already configured');
    }
    console.log();
    console.log('This Codex config is shared by the Codex CLI and IDE extension.');
    console.log('Restart Codex / VS Code if it was already open.');
}
export async function uninstallCodex() {
    const existing = readConfig();
    const result = removeServerBlock(existing);
    if (!result.changed) {
        console.log('ShieldCortex MCP server was not configured for Codex.');
        return;
    }
    writeConfig(result.content);
    console.log(`✓ Codex — removed ShieldCortex from ${getCodexConfigPath()}`);
}
export async function codexStatus() {
    const content = readConfig();
    console.log(`Codex config: ${getCodexConfigPath()}`);
    console.log(`  Exists: ${content.length > 0 ? 'yes' : 'no'}`);
    console.log(`  Configured: ${hasServerBlock(content) ? 'yes' : 'no'}`);
    console.log(`  MCP entry: ${MCP_ENTRY}`);
    console.log(`  Entry exists: ${fs.existsSync(MCP_ENTRY) ? 'yes' : 'no'}`);
}
export async function handleCodexCommand(subcommand) {
    console.log();
    switch (subcommand) {
        case 'install':
            await installCodex();
            break;
        case 'uninstall':
            await uninstallCodex();
            break;
        case 'status':
            await codexStatus();
            break;
        default:
            console.log('Usage: shieldcortex codex <install|uninstall|status>');
            console.log();
            console.log('Configures ShieldCortex in ~/.codex/config.toml for Codex CLI');
            console.log('and the Codex VS Code extension.');
            process.exit(1);
    }
}
