import { buildMcpDoctorReport, repairMcpDoctorIssues } from "../commands/mcp.js";
import { getProjectRoot, getUserHome } from "../util/fs.js";
import { style } from "../util/theme.js";
import { maskSensitiveText } from "../util/secret-mask.js";
import { isAbsolute, join, relative } from "path";
export async function runMcpAutoConnect(options = {}) {
    const preflight = normalizePreflightMode(options.preflight);
    const env = buildAutoConnectEnv(preflight, options.env);
    const fixes = options.fix
        ? await repairMcpDoctorIssues({ dryRun: Boolean(options.dryRun), global: Boolean(options.global) })
        : undefined;
    void env;
    const doctor = await buildMcpDoctorReport();
    return mapDoctorToAutoConnectReport(doctor, { preflight, fixes });
}
export function mapDoctorToAutoConnectReport(doctor, options = {}) {
    const preflight = normalizePreflightMode(options.preflight);
    const autoMounted = doctor.servers
        .filter((server) => server.active)
        .map((server) => mapServerToEntry(server));
    const data = summarizeEntries(autoMounted);
    const coreMounted = autoMounted.some((entry) => entry.name === "omk-project" && entry.status !== "error");
    const ok = doctor.activeScope === "none" ? true : coreMounted;
    return {
        command: "mcp connect",
        ok,
        degraded: doctor.errors.length > 0 || doctor.warnings.length > 0 || data.error > 0 || data.warning > 0,
        checkedAt: doctor.checkedAt,
        scope: doctor.activeScope,
        preflight,
        autoMounted,
        sources: doctor.sources.map(mapSourceReport),
        errors: doctor.errors.map(maskSensitiveText),
        warnings: doctor.warnings.map(maskSensitiveText),
        fixes: options.fixes,
        data,
    };
}
export function renderMcpAutoConnectBanner(report) {
    return renderMcpAutoConnectLines(report).join("\n");
}
export function renderMcpAutoConnectLines(report) {
    const modeLabel = report.preflight === "full" ? "full/preflight" : report.preflight === "fast" ? "fast/offline" : "off/offline";
    const statusLabel = !report.ok ? "error" : report.degraded ? "ready with optional warnings" : "ready";
    const lines = [
        style.purpleBold("MCP Tool Plane"),
        [
            `MCP: ${report.scope} scope`,
            `${report.data.active} active`,
            `${report.data.ready + report.data.mounted} ready`,
            `${report.data.warning} warning`,
            `${report.data.error} error`,
            modeLabel,
        ].join(" · "),
        `Status: ${statusLabel}`,
    ];
    if (report.autoMounted.length === 0) {
        lines.push("  no active MCP servers; run `omk mcp connect --fix` to create project-local MCP config");
        return lines;
    }
    for (const entry of report.autoMounted.slice(0, 6)) {
        lines.push(formatAutoConnectEntry(entry));
    }
    if (report.autoMounted.length > 6) {
        lines.push(`  … ${report.autoMounted.length - 6} more active MCP server(s); run \`omk mcp connect --json\``);
    }
    const hasVirtualProjectMcp = report.autoMounted.some((entry) => entry.name === "omk-project" && entry.source === "builtin");
    if (hasVirtualProjectMcp) {
        lines.push("  Offline snapshot only; no MCP servers were started.");
        lines.push("  Built-in omk-project MCP mounted; full validation: omk mcp doctor && omk mcp connect --all");
    }
    if (report.fixes) {
        const fixMode = report.fixes.dryRun ? "previewed" : report.fixes.changed ? "applied" : "checked";
        lines.push(`  Fixes: ${fixMode} ${report.fixes.actions.length} action(s); ${report.fixes.skipped.length} skipped`);
    }
    if (report.degraded) {
        lines.push("  degraded: optional MCP issues do not block root startup; run `omk mcp connect --fix` or `omk mcp doctor`");
    }
    return lines;
}
export async function mcpConnectCommand(options = {}) {
    const report = await runMcpAutoConnect({
        fix: Boolean(options.fix),
        preflight: options.all ? "full" : "fast",
    });
    if (options.json) {
        console.log(JSON.stringify(report, null, 2));
        if (!report.ok)
            process.exitCode = 1;
        return;
    }
    console.log(renderMcpAutoConnectBanner(report));
    if (!report.ok)
        process.exitCode = 1;
}
function normalizePreflightMode(mode) {
    return mode === "full" || mode === "off" || mode === "fast" ? mode : "fast";
}
function buildAutoConnectEnv(preflight, env = process.env) {
    if (preflight === "full") {
        return { ...env, OMK_MCP_PREFLIGHT: env.OMK_MCP_PREFLIGHT && env.OMK_MCP_PREFLIGHT !== "off" ? env.OMK_MCP_PREFLIGHT : "warn-skip" };
    }
    return { ...env, OMK_MCP_PREFLIGHT: "off" };
}
function summarizeEntries(entries) {
    return {
        active: entries.length,
        ready: entries.filter((entry) => entry.status === "ready").length,
        mounted: entries.filter((entry) => entry.status === "mounted").length,
        warning: entries.filter((entry) => entry.status === "warn").length,
        error: entries.filter((entry) => entry.status === "error").length,
    };
}
function mapSourceReport(source) {
    return {
        path: maskSensitiveText(source.path),
        exists: source.exists,
        active: source.active,
        parsed: source.parsed,
        status: source.status,
    };
}
function mapServerToEntry(server) {
    const virtualProject = server.name === "omk-project" && server.sources.includes("runtime:auto-injected");
    const statusValue = virtualProject
        ? "mounted"
        : server.status === "ok"
            ? "ready"
            : server.status === "warn"
                ? "warn"
                : "error";
    return {
        name: server.name,
        transport: server.transport,
        source: classifySource(server.activeSources[0] ?? server.sources[0]),
        status: statusValue,
        reason: firstReason(server),
    };
}
function classifySource(source) {
    if (!source)
        return "runtime";
    if (source === "runtime:auto-injected")
        return "builtin";
    const home = getUserHome();
    const globalKimi = join(home, ".kimi", "mcp.json");
    const globalOmk = join(home, ".omk", "mcp.json");
    if (source === globalKimi || source === globalOmk)
        return "global";
    const root = getProjectRoot();
    const relativeToProject = relative(root, source);
    if (relativeToProject === "" || (!relativeToProject.startsWith("..") && !isAbsolute(relativeToProject)))
        return "project";
    return "runtime";
}
function firstReason(server) {
    const check = server.checks.find((item) => item.severity === "error")
        ?? server.checks.find((item) => item.severity === "warn")
        ?? server.checks.find((item) => item.kind === "virtual-runtime-injected")
        ?? server.checks[0];
    return check?.message ? maskSensitiveText(check.message) : undefined;
}
function formatAutoConnectEntry(entry) {
    const icon = entry.status === "error" ? "✗" : entry.status === "warn" ? "⚠" : "✓";
    const coloredIcon = entry.status === "error" ? style.pink(icon) : entry.status === "warn" ? style.skin(icon) : style.mint(icon);
    const suffix = entry.reason ? ` — ${entry.reason}` : "";
    return `  ${coloredIcon} ${entry.name.padEnd(20)} ${formatStatusLabel(entry.status).padEnd(15)} ${formatSourceLabel(entry.source).padEnd(8)} ${entry.transport}${suffix}`;
}
function formatStatusLabel(status) {
    switch (status) {
        case "mounted":
            return "Mounted";
        case "ready":
            return "Ready";
        case "warn":
            return "Needs attention";
        case "error":
            return "Error";
    }
}
function formatSourceLabel(source) {
    switch (source) {
        case "builtin":
            return "Built-in";
        case "project":
            return "Project";
        case "global":
            return "Global";
        case "runtime":
            return "Runtime";
    }
}
