"use strict";
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 () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ShellProfileInstaller = void 0;
const fs = __importStar(require("fs"));
const path = __importStar(require("path"));
const os = __importStar(require("os"));
const MARKER_START = '# >>> splitgame auto-launch >>>';
const MARKER_END = '# <<< splitgame auto-launch <<<';
const SHELL_PROFILES = {
    bash: ['.bashrc'],
    zsh: ['.zshrc'],
    fish: [path.join('.config', 'fish', 'config.fish')],
};
function buildSnippet(shell) {
    if (shell === 'fish') {
        return [
            MARKER_START,
            'if not set -q SPLITGAME_ACTIVE; and status is-interactive; and isatty stdout; and command -q splitgame',
            '  set -gx SPLITGAME_ACTIVE 1',
            '  exec splitgame $SHELL',
            'end',
            MARKER_END,
        ].join('\n');
    }
    return [
        MARKER_START,
        'if [ -z "$SPLITGAME_ACTIVE" ] && [ -t 1 ] && command -v splitgame >/dev/null 2>&1; then',
        '  export SPLITGAME_ACTIVE=1',
        '  exec splitgame "$SHELL"',
        'fi',
        MARKER_END,
    ].join('\n');
}
class ShellProfileInstaller {
    splitgameDir;
    manifestPath;
    homeDir;
    constructor(options) {
        this.homeDir = options?.homeDir ?? os.homedir();
        this.splitgameDir = options?.splitgameDir ?? path.join(this.homeDir, '.splitgame');
        this.manifestPath = path.join(this.splitgameDir, 'install-manifest.json');
    }
    install() {
        this.ensureSplitgameInPath();
        const existing = this.getManifest();
        if (existing) {
            return {
                shell: existing.shell,
                profilePath: existing.profilePath,
                backupPath: existing.backupPath,
                alreadyInstalled: true,
            };
        }
        const shell = this.detectShell();
        const profilePath = this.findProfilePath(shell);
        if (!profilePath) {
            throw new Error(`Could not find shell profile for ${shell}.\n` +
                `Checked: ${(SHELL_PROFILES[shell] || []).map(f => path.join(this.homeDir, f)).join(', ')}`);
        }
        const backupDir = path.join(this.splitgameDir, 'backups');
        this.ensureDir(backupDir);
        const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
        const backupPath = path.join(backupDir, `${path.basename(profilePath)}.${timestamp}.bak`);
        let originalContent = '';
        try {
            originalContent = fs.readFileSync(profilePath, 'utf-8');
        }
        catch {
            // File doesn't exist yet — will be created
        }
        if (originalContent.includes(MARKER_START)) {
            return {
                shell,
                profilePath,
                backupPath,
                alreadyInstalled: true,
            };
        }
        if (originalContent) {
            fs.writeFileSync(backupPath, originalContent, 'utf-8');
        }
        const snippet = buildSnippet(shell);
        const newContent = originalContent
            ? originalContent.replace(/\n*$/, '\n\n') + snippet + '\n'
            : snippet + '\n';
        fs.writeFileSync(profilePath, newContent, 'utf-8');
        const manifest = {
            version: 1,
            installedAt: new Date().toISOString(),
            platform: process.platform,
            shell,
            profilePath,
            backupPath,
        };
        this.ensureDir(this.splitgameDir);
        fs.writeFileSync(this.manifestPath, JSON.stringify(manifest, null, 2), 'utf-8');
        return { shell, profilePath, backupPath, alreadyInstalled: false };
    }
    uninstall() {
        const manifest = this.getManifest();
        if (!manifest) {
            // No manifest — check if marker exists in common profiles
            const shell = this.detectShell();
            const profilePath = this.findProfilePath(shell);
            if (profilePath) {
                try {
                    const content = fs.readFileSync(profilePath, 'utf-8');
                    if (content.includes(MARKER_START)) {
                        this.removeSnippet(profilePath, content);
                        return { profilePath, notInstalled: false };
                    }
                }
                catch {
                    // file doesn't exist
                }
            }
            return { profilePath: '', notInstalled: true };
        }
        try {
            const content = fs.readFileSync(manifest.profilePath, 'utf-8');
            if (content.includes(MARKER_START)) {
                this.removeSnippet(manifest.profilePath, content);
            }
        }
        catch {
            // Profile file gone — nothing to restore
        }
        try {
            fs.unlinkSync(this.manifestPath);
        }
        catch {
            // manifest already gone
        }
        return { profilePath: manifest.profilePath, notInstalled: false };
    }
    getManifest() {
        try {
            const raw = fs.readFileSync(this.manifestPath, 'utf-8');
            const manifest = JSON.parse(raw);
            if (manifest.shell)
                return manifest;
            return null;
        }
        catch {
            return null;
        }
    }
    removeSnippet(profilePath, content) {
        const startIdx = content.indexOf(MARKER_START);
        const endIdx = content.indexOf(MARKER_END);
        if (startIdx === -1 || endIdx === -1)
            return;
        const before = content.slice(0, startIdx).replace(/\n+$/, '\n');
        const after = content.slice(endIdx + MARKER_END.length).replace(/^\n+/, '');
        const cleaned = before + (after ? '\n' + after : '');
        fs.writeFileSync(profilePath, cleaned, 'utf-8');
    }
    detectShell() {
        const shellPath = process.env.SHELL || '/bin/bash';
        const shellName = path.basename(shellPath);
        if (SHELL_PROFILES[shellName])
            return shellName;
        return 'bash';
    }
    findProfilePath(shell) {
        const candidates = SHELL_PROFILES[shell];
        if (!candidates)
            return null;
        for (const rel of candidates) {
            const full = path.join(this.homeDir, rel);
            try {
                fs.accessSync(full, fs.constants.R_OK);
                return full;
            }
            catch {
                continue;
            }
        }
        // Profile doesn't exist yet — return the first candidate so we can create it
        return path.join(this.homeDir, candidates[0]);
    }
    ensureSplitgameInPath() {
        const pathDirs = (process.env.PATH || '').split(path.delimiter);
        for (const dir of pathDirs) {
            try {
                fs.accessSync(path.join(dir, 'splitgame'), fs.constants.X_OK);
                return;
            }
            catch {
                continue;
            }
        }
        throw new Error('splitgame is not globally installed (not found in PATH).\n\n' +
            'Run one of:\n' +
            '  npm install -g splitgame\n' +
            '  npm link           (from the splitgame project directory)');
    }
    ensureDir(dir) {
        try {
            fs.mkdirSync(dir, { recursive: true });
        }
        catch {
            // already exists
        }
    }
}
exports.ShellProfileInstaller = ShellProfileInstaller;
//# sourceMappingURL=shell-installer.js.map