import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
import { homedir } from "node:os";
import { dirname, join } from "node:path";
const THREADWELL_WEZTERM_BLOCK_START = "-- >>> Threadwell recommended tweak: keyboard mappings";
const THREADWELL_WEZTERM_BLOCK_END = "-- <<< Threadwell recommended tweak: keyboard mappings";
const LEGACY_THREADWELL_WEZTERM_BLOCK_START = "-- >>> Threadwell recommended tweak: Shift+Enter newline";
const LEGACY_THREADWELL_WEZTERM_BLOCK_END = "-- <<< Threadwell recommended tweak: Shift+Enter newline";
function escapeRegExp(value) {
    return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
function candidateWezTermConfigPaths() {
    const home = homedir();
    return [join(home, ".wezterm.lua"), join(home, ".config", "wezterm", "wezterm.lua")];
}
function selectWezTermConfigPath() {
    const candidates = candidateWezTermConfigPaths();
    return candidates.find((path) => existsSync(path)) ?? candidates[0];
}
function entryLines(tweak) {
    switch (tweak) {
        case "wezterm-shift-enter":
            return [
                "{",
                "\tkey = 'Enter',",
                "\tmods = 'SHIFT',",
                "\taction = wezterm.action.SendString('\\x1b[13;2u'),",
                "},",
            ];
        case "wezterm-ctrl-word-delete":
            return [
                "{",
                "\tkey = 'Backspace',",
                "\tmods = 'CTRL',",
                "\taction = wezterm.action.SendString('\\x1b[127;5u'),",
                "},",
                "{",
                "\tkey = 'Delete',",
                "\tmods = 'CTRL',",
                "\taction = wezterm.action.SendString('\\x1b[3;5~'),",
                "},",
            ];
    }
}
function detectInstalledTweaks(content) {
    const installed = new Set();
    if (content.includes("\\x1b[13;2u"))
        installed.add("wezterm-shift-enter");
    if (content.includes("\\x1b[127;5u") || content.includes("\\x1b[3;5~")) {
        installed.add("wezterm-ctrl-word-delete");
    }
    return installed;
}
function buildConfigBlock(tweaks) {
    const lines = [THREADWELL_WEZTERM_BLOCK_START, "config.keys = config.keys or {}"];
    for (const tweak of tweaks) {
        const entries = entryLines(tweak);
        let current = [];
        for (const line of entries) {
            current.push(line);
            if (line === "},") {
                lines.push("table.insert(config.keys, {");
                lines.push(...current.slice(1, -1));
                lines.push("})");
                current = [];
            }
        }
    }
    lines.push(THREADWELL_WEZTERM_BLOCK_END);
    return lines.join("\n");
}
function buildTableFieldsBlock(tweaks) {
    const entries = [...tweaks].flatMap((tweak) => entryLines(tweak).map((line) => `\t\t${line}`));
    return [THREADWELL_WEZTERM_BLOCK_START, "\tkeys = {", ...entries, "\t},", THREADWELL_WEZTERM_BLOCK_END].join("\n");
}
function threadwellBlockPattern() {
    const current = `${escapeRegExp(THREADWELL_WEZTERM_BLOCK_START)}[\\s\\S]*?${escapeRegExp(THREADWELL_WEZTERM_BLOCK_END)}`;
    const legacy = `${escapeRegExp(LEGACY_THREADWELL_WEZTERM_BLOCK_START)}[\\s\\S]*?${escapeRegExp(LEGACY_THREADWELL_WEZTERM_BLOCK_END)}`;
    return new RegExp(`${current}|${legacy}`, "u");
}
export function getWezTermTweaksStatus() {
    const path = selectWezTermConfigPath();
    if (!existsSync(path)) {
        return { path, installed: [], hasThreadwellBlock: false };
    }
    const content = readFileSync(path, "utf-8");
    return {
        path,
        installed: [...detectInstalledTweaks(content)],
        hasThreadwellBlock: threadwellBlockPattern().test(content),
    };
}
function createDefaultWezTermConfig(path, tweaks) {
    mkdirSync(dirname(path), { recursive: true });
    const content = [
        "local wezterm = require 'wezterm'",
        "local config = wezterm.config_builder()",
        "",
        buildConfigBlock(tweaks),
        "",
        "return config",
        "",
    ].join("\n");
    writeFileSync(path, content, "utf-8");
    return { path, changed: true, message: "Created WezTerm config with Threadwell tweaks" };
}
export function applyWezTermTweaks(requestedTweaks) {
    const path = selectWezTermConfigPath();
    const requested = new Set(requestedTweaks);
    if (!existsSync(path)) {
        return createDefaultWezTermConfig(path, requested);
    }
    const original = readFileSync(path, "utf-8");
    const timestamp = new Date().toISOString().replace(/[:.]/g, "-");
    const backupPath = `${path}.threadwell-backup-${timestamp}`;
    const blockPattern = threadwellBlockPattern();
    const hasConfigReturn = /(^|\n)(\s*)return\s+config\b[^\n]*(?=\n|$)/u.test(original);
    const installed = detectInstalledTweaks(original);
    for (const tweak of requested)
        installed.add(tweak);
    const replacement = hasConfigReturn ? buildConfigBlock(installed) : buildTableFieldsBlock(installed);
    if (blockPattern.test(original)) {
        const updated = original.replace(blockPattern, replacement);
        if (updated === original)
            return { path, changed: false, message: "Threadwell WezTerm tweaks are already installed" };
        copyFileSync(path, backupPath);
        writeFileSync(path, updated, "utf-8");
        return { path, changed: true, backupPath, message: "Updated WezTerm tweaks" };
    }
    const returnConfigPattern = /(^|\n)(\s*)return\s+config\b[^\n]*(?=\n|$)/gu;
    const matches = [...original.matchAll(returnConfigPattern)];
    const lastReturn = matches.at(-1);
    if (lastReturn?.index !== undefined) {
        copyFileSync(path, backupPath);
        const insertAt = lastReturn.index + (lastReturn[1] === "\n" ? 1 : 0);
        const updated = `${original.slice(0, insertAt)}${replacement}\n\n${original.slice(insertAt)}`;
        writeFileSync(path, updated, "utf-8");
        return { path, changed: true, backupPath, message: "Installed WezTerm tweaks" };
    }
    const returnTablePattern = /(^|\n)(\s*)return\s*\{/u;
    const returnTable = returnTablePattern.exec(original);
    if (!returnTable || returnTable.index === undefined) {
        return {
            path,
            changed: false,
            message: "Could not safely patch WezTerm config: expected `return config` or `return {`",
        };
    }
    if (/\bkeys\s*=/u.test(original)) {
        return {
            path,
            changed: false,
            message: "Could not safely patch table-style WezTerm config: keys already exists",
        };
    }
    copyFileSync(path, backupPath);
    const insertAt = returnTable.index + returnTable[0].length;
    const updated = `${original.slice(0, insertAt)}\n${replacement}\n${original.slice(insertAt)}`;
    writeFileSync(path, updated, "utf-8");
    return { path, changed: true, backupPath, message: "Installed WezTerm tweaks" };
}
export function applyWezTermShiftEnterTweak() {
    return applyWezTermTweaks(["wezterm-shift-enter"]);
}
//# sourceMappingURL=wezterm-tweaks.js.map