/**
 * /sandbox slash command handler.
 *
 * - Not installed → runs WSL2 + bubblewrap setup flow
 * - Already installed → shows settings menu (enable/disable, network, write paths, allowed domains)
 */
import chalk from 'chalk';
import { execSync } from 'node:child_process';
import { existsSync } from 'node:fs';
import { getAlpineRootfsPath, getSettingsPath, getWslDir, VERSION } from '../../config.js';
import { enableWsl2, ensureWslSandbox, isDistroInstalled, isWsl2Available, DEFAULT_DISTRO as SANDBOX_DISTRO } from './lib/index.js';
const WSL_INSTALL_HINT = '\n\n  To fix this:\n' +
    '  1. Open PowerShell or Command Prompt as Administrator\n' +
    '  2. Run: wsl --install\n' +
    '  3. Reboot your computer\n' +
    '  4. Restart shortcutXL and type /sandbox to continue setup';
function errorWithHint(reason) {
    return chalk.red(reason + WSL_INSTALL_HINT);
}
/**
 * Handle the /sandbox slash command.
 *
 * Orchestrates the full setup flow (WSL2 check, distro import) or
 * opens the settings menu if the sandbox is already installed.
 * Returns true to indicate the command was handled.
 */
export async function handleSandboxCommand(showStatus, select, input, settingsManager) {
    // Step 1: Check WSL2
    if (!isWsl2Available()) {
        showStatus('Enabling WSL2 (you may see a permissions prompt)...');
        const result = enableWsl2();
        if (!result.success) {
            showStatus(errorWithHint('Could not enable WSL2.'));
            return true;
        }
        if (result.needsReboot) {
            showStatus(errorWithHint('WSL2 enabled but a reboot is required.'));
            return true;
        }
    }
    // Step 2: Already installed → show settings menu
    if (isDistroInstalled(SANDBOX_DISTRO)) {
        await showSettingsMenu(showStatus, select, input, settingsManager);
        return true;
    }
    // Step 3: Not installed → set up
    const rootfsExists = existsSync(getAlpineRootfsPath());
    showStatus(rootfsExists
        ? 'Setting up sandbox (importing Alpine Linux + bubblewrap)...'
        : 'Downloading sandbox (~80 MB) and setting up...');
    const result = await ensureWslSandbox({
        distro: SANDBOX_DISTRO,
        wslDir: getWslDir(),
        rootfsPath: getAlpineRootfsPath(),
        version: VERSION
    });
    if (result.installed) {
        settingsManager.setSandboxMode('enabled');
        showStatus('Sandbox ready — restart session to activate');
    }
    else {
        showStatus(errorWithHint(`Sandbox setup failed: ${result.error ?? 'unknown error'}`));
    }
    return true;
}
// ---------------------------------------------------------------------------
// Settings menu (post-install)
// ---------------------------------------------------------------------------
async function showSettingsMenu(showStatus, select, input, sm) {
    while (true) {
        const isOn = sm.getSandboxMode() === 'enabled';
        const networkMode = sm.getSandboxNetworkMode();
        const settings = sm.getSandboxSettings();
        const readPaths = settings.readPaths ?? [];
        const writePaths = settings.writePaths ?? [];
        const allowedDomains = settings.allowedDomains ?? [];
        const choice = await select('Sandbox Settings', [
            isOn ? 'Disable sandbox' : 'Enable sandbox',
            `Network: ${networkMode}`,
            `Read paths (${readPaths.length})`,
            `Write paths (${writePaths.length})`,
            `Allowed domains (${allowedDomains.length})`,
            'Reset to defaults',
            'Open config file',
            'Cancel'
        ]);
        if (!choice || choice === 'Cancel')
            return;
        if (choice === 'Enable sandbox') {
            sm.setSandboxMode('enabled');
            showStatus('Sandbox enabled — restart session to activate');
        }
        else if (choice === 'Disable sandbox') {
            sm.setSandboxMode('disabled');
            showStatus('Sandbox disabled — restart session to deactivate');
        }
        else if (choice.startsWith('Network:')) {
            await showNetworkMenu(showStatus, select, sm);
        }
        else if (choice.startsWith('Read paths')) {
            await showListMenu('Read Paths', readPaths, showStatus, select, input, {
                placeholder: 'D:\\SharedData',
                onSave: (paths) => sm.setSandboxReadPaths(paths)
            });
        }
        else if (choice.startsWith('Write paths')) {
            await showListMenu('Write Paths', writePaths, showStatus, select, input, {
                placeholder: 'C:\\Users\\you\\Downloads',
                onSave: (paths) => sm.setSandboxWritePaths(paths)
            });
        }
        else if (choice.startsWith('Allowed domains')) {
            await showListMenu('Allowed Domains', allowedDomains, showStatus, select, input, {
                placeholder: '*.github.com',
                onSave: (domains) => sm.setSandboxAllowedDomains(domains)
            });
        }
        else if (choice === 'Reset to defaults') {
            sm.resetSandboxToDefaults();
            showStatus('Sandbox settings reset to defaults — takes effect on next command');
        }
        else if (choice === 'Open config file') {
            const configPath = getSettingsPath();
            try {
                execSync(`start "" "${configPath}"`);
                showStatus(`Opened ${configPath}`);
            }
            catch {
                showStatus(`Config file: ${configPath}`);
            }
        }
    }
}
// ---------------------------------------------------------------------------
// Network mode sub-menu
// ---------------------------------------------------------------------------
async function showNetworkMenu(showStatus, select, sm) {
    const current = sm.getSandboxNetworkMode();
    const modes = ['none', 'proxy', 'full'];
    const labels = {
        none: 'None — no network access',
        proxy: 'Proxy — domain-level control with approval prompts',
        full: 'Full — unrestricted network access'
    };
    const options = modes.map((m) => (m === current ? `${labels[m]} (current)` : labels[m]));
    options.push('Cancel');
    const choice = await select('Network Mode', options);
    if (!choice || choice === 'Cancel')
        return;
    const selected = modes.find((m) => choice.startsWith(labels[m]));
    if (selected && selected !== current) {
        sm.setSandboxNetworkMode(selected);
        showStatus(`Network mode set to '${selected}' — takes effect on the next command`);
    }
}
async function showListMenu(title, items, showStatus, select, input, opts) {
    const options = ['+ Add...', ...items.map((item) => `  ${item}`), 'Cancel'];
    const choice = await select(title, options);
    if (!choice || choice === 'Cancel')
        return;
    if (choice === '+ Add...') {
        const value = await input(`Add to ${title}`, opts.placeholder);
        if (value && value.trim()) {
            const trimmed = value.trim();
            if (!items.includes(trimmed)) {
                opts.onSave([...items, trimmed]);
                showStatus(`Added: ${trimmed} — takes effect on next command`);
            }
            else {
                showStatus(`Already in list: ${trimmed}`);
            }
        }
    }
    else {
        // Selected an existing item → offer to remove it
        const item = choice.replace(/^\s+/, '');
        const confirm = await select(`Remove "${item}"?`, ['Remove', 'Cancel']);
        if (confirm === 'Remove') {
            opts.onSave(items.filter((i) => i !== item));
            showStatus(`Removed: ${item} — takes effect on next command`);
        }
    }
}
//# sourceMappingURL=sandbox-command.js.map