"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createCompletionScript = createCompletionScript;
exports.installCompletionIntegration = installCompletionIntegration;
exports.uninstallCompletionIntegration = uninstallCompletionIntegration;
const node_fs_1 = __importDefault(require("node:fs"));
const node_os_1 = __importDefault(require("node:os"));
const node_path_1 = __importDefault(require("node:path"));
const MANAGED_START_MARKER = "# >>> day-shift completion >>>";
const MANAGED_END_MARKER = "# <<< day-shift completion <<<";
function createCompletionScript(shell) {
    const script = shell === "bash"
        ? createBashCompletionScript()
        : shell === "zsh"
            ? createZshCompletionScript()
            : createFishCompletionScript();
    return wrapManagedBlock(script);
}
function installCompletionIntegration(options) {
    const dryRun = options.dryRun ?? false;
    const force = options.force ?? false;
    const targetPath = resolveCompletionTargetPath(options.shell);
    const script = `${createCompletionScript(options.shell)}\n`;
    const existing = node_fs_1.default.existsSync(targetPath)
        ? node_fs_1.default.readFileSync(targetPath, "utf8")
        : null;
    const plan = planCompletionInstall({
        shell: options.shell,
        targetPath,
        existing,
        script,
        dryRun,
        force
    });
    if (!dryRun && plan.changed) {
        node_fs_1.default.mkdirSync(node_path_1.default.dirname(targetPath), { recursive: true });
        node_fs_1.default.writeFileSync(targetPath, planCompletionInstallContents(existing, script, options.shell, force), "utf8");
    }
    return plan;
}
function uninstallCompletionIntegration(options) {
    const dryRun = options.dryRun ?? false;
    const targetPath = resolveCompletionTargetPath(options.shell);
    const existing = node_fs_1.default.existsSync(targetPath)
        ? node_fs_1.default.readFileSync(targetPath, "utf8")
        : null;
    const plan = planCompletionUninstall({
        shell: options.shell,
        targetPath,
        existing,
        dryRun
    });
    if (!dryRun && plan.changed && existing !== null) {
        if (plan.action === "remove-file") {
            node_fs_1.default.rmSync(targetPath);
        }
        else {
            node_fs_1.default.writeFileSync(targetPath, removeManagedBlock(existing), "utf8");
        }
    }
    return plan;
}
function createBashCompletionScript() {
    return [
        "_day_shift_completion() {",
        "  local line cursor output candidate description",
        "  line=\"${COMP_LINE}\"",
        "  cursor=\"${COMP_POINT}\"",
        "  output=\"$(day-shift completion complete --shell bash --line \"$line\" --cursor \"$cursor\" 2>/dev/null)\" || return 0",
        "  COMPREPLY=()",
        "  while IFS=$'\\t' read -r candidate description; do",
        "    [[ -n \"$candidate\" ]] && COMPREPLY+=(\"$candidate\")",
        "  done <<< \"$output\"",
        "}",
        "complete -F _day_shift_completion day-shift"
    ].join("\n");
}
function createZshCompletionScript() {
    return [
        "#compdef day-shift",
        "_day_shift_completion() {",
        "  local -a completions",
        "  local line cursor output candidate description",
        "  line=\"$BUFFER\"",
        "  cursor=\"$CURSOR\"",
        "  output=\"$(day-shift completion complete --shell zsh --line \"$line\" --cursor \"$cursor\" 2>/dev/null)\" || return 0",
        "  completions=()",
        "  while IFS=$'\\t' read -r candidate description; do",
        "    [[ -n \"$candidate\" ]] && completions+=(\"$candidate:$description\")",
        "  done <<< \"$output\"",
        "  _describe 'day-shift' completions",
        "}",
        "compdef _day_shift_completion day-shift"
    ].join("\n");
}
function createFishCompletionScript() {
    return [
        "function __day_shift_complete",
        "    set -l line (commandline -cp)",
        "    set -l cursor (string length -- \"$line\")",
        "    day-shift completion complete --shell fish --line \"$line\" --cursor \"$cursor\"",
        "end",
        "complete -c day-shift -f -a \"(__day_shift_complete)\""
    ].join("\n");
}
function wrapManagedBlock(script) {
    return [
        MANAGED_START_MARKER,
        script,
        MANAGED_END_MARKER
    ].join("\n");
}
function resolveCompletionTargetPath(shell) {
    const home = process.env.HOME ?? node_os_1.default.homedir();
    if (!home) {
        throw new Error("Could not resolve a home directory for completion integration.");
    }
    if (shell === "bash") {
        return node_path_1.default.join(home, ".bashrc");
    }
    if (shell === "zsh") {
        return node_path_1.default.join(home, ".zshrc");
    }
    const configHome = process.env.XDG_CONFIG_HOME ?? node_path_1.default.join(home, ".config");
    return node_path_1.default.join(configHome, "fish", "completions", "day-shift.fish");
}
function planCompletionInstall(options) {
    if (options.existing === null) {
        return {
            shell: options.shell,
            targetPath: options.targetPath,
            dryRun: options.dryRun,
            force: options.force,
            action: "create",
            changed: true,
            reason: "Completion target does not exist; create it with the Day Shift-managed integration."
        };
    }
    if (hasManagedBlock(options.existing)) {
        const next = replaceManagedBlock(options.existing, options.script);
        return {
            shell: options.shell,
            targetPath: options.targetPath,
            dryRun: options.dryRun,
            force: options.force,
            action: next === options.existing ? "noop" : "update",
            changed: next !== options.existing,
            reason: next === options.existing
                ? "Managed completion integration already matches the intended script."
                : "Update the existing Day Shift-managed completion integration."
        };
    }
    if (options.shell === "fish" && options.existing.trim().length > 0 && !options.force) {
        return {
            shell: options.shell,
            targetPath: options.targetPath,
            dryRun: options.dryRun,
            force: options.force,
            action: "blocked",
            changed: false,
            reason: "Fish completion file exists without Day Shift managed markers; rerun with --force only if replacement is intended."
        };
    }
    return {
        shell: options.shell,
        targetPath: options.targetPath,
        dryRun: options.dryRun,
        force: options.force,
        action: options.shell === "fish" && options.force ? "overwrite" : "append",
        changed: true,
        reason: options.shell === "fish" && options.force
            ? "Replace the shell-native Day Shift completion file after explicit --force intent."
            : "Append a Day Shift-managed completion block and preserve existing shell configuration."
    };
}
function planCompletionInstallContents(existing, script, shell, force) {
    if (existing === null) {
        return script;
    }
    if (hasManagedBlock(existing)) {
        return replaceManagedBlock(existing, script);
    }
    if (shell === "fish" && force) {
        return script;
    }
    const separator = existing.endsWith("\n") ? "" : "\n";
    return `${existing}${separator}\n${script}`;
}
function planCompletionUninstall(options) {
    if (options.existing === null || !hasManagedBlock(options.existing)) {
        return {
            shell: options.shell,
            targetPath: options.targetPath,
            dryRun: options.dryRun,
            action: "noop",
            changed: false,
            reason: "No Day Shift-managed completion integration was found."
        };
    }
    const next = removeManagedBlock(options.existing);
    const removeFile = options.shell === "fish" && next.trim().length === 0;
    return {
        shell: options.shell,
        targetPath: options.targetPath,
        dryRun: options.dryRun,
        action: removeFile ? "remove-file" : "remove-block",
        changed: true,
        reason: removeFile
            ? "Remove the Day Shift-owned fish completion file."
            : "Remove only the Day Shift-managed completion block."
    };
}
function hasManagedBlock(contents) {
    return contents.includes(MANAGED_START_MARKER) && contents.includes(MANAGED_END_MARKER);
}
function replaceManagedBlock(contents, replacement) {
    return contents.replace(createManagedBlockPattern(), () => replacement);
}
function removeManagedBlock(contents) {
    return contents.replace(createManagedBlockPattern(), "").replace(/\n{3,}/g, "\n\n");
}
function createManagedBlockPattern() {
    return new RegExp(`${escapeRegExp(MANAGED_START_MARKER)}[\\s\\S]*?${escapeRegExp(MANAGED_END_MARKER)}\\n?`, "m");
}
function escapeRegExp(value) {
    return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
