/**
 * Interactive virtual shell CLI
 *
 * Usage:
 *   npx tsx src/cli/shell.ts [--cwd <dir>] [--files <json-file>]
 *
 * This provides an interactive shell experience using Bash's virtual filesystem.
 */
import * as fs from "node:fs";
import * as path from "node:path";
import * as readline from "node:readline";
import { fileURLToPath } from "node:url";
import { Bash } from "../Bash.js";
import { OverlayFs } from "../fs/overlay-fs/overlay-fs.js";
import { getErrorMessage } from "../interpreter/helpers/errors.js";
import { DiscoveryService, } from "../services/DiscoveryService.js";
import { Theme } from "./theme.js";
const __dirname = path.dirname(fileURLToPath(import.meta.url));
class VirtualShell {
    env;
    rl;
    running = true;
    history = [];
    discovery;
    projectBrief = null;
    isInteractive;
    constructor(options = {}) {
        // Use OverlayFs with current directory as root
        const root = process.cwd();
        const overlayFs = new OverlayFs({
            root,
            mountPoint: "/",
        });
        this.env = new Bash({
            fs: overlayFs,
            cwd: options.cwd || "/",
            env: {
                HOME: "/",
                USER: "user",
                SHELL: "/bin/bash",
                TERM: "xterm-256color",
                ...options.env,
            },
            // Network disabled by default; use --network to enable
            network: options.network === true
                ? { dangerouslyAllowFullInternetAccess: true }
                : undefined,
            runtimes: {
                python: options.python ?? true,
                javascript: options.javascript ?? true,
            },
            parser: {
                engine: "tree-sitter",
                treeSitterConfig: {
                    webTreeSitterWasm: path.join(__dirname, "../parser/vendor/web-tree-sitter.wasm"),
                    bashGrammarWasm: path.join(__dirname, "../../vendor/tree-sitter-bash.wasm"),
                },
            },
        });
        // Check if stdin is a TTY (interactive mode)
        this.isInteractive = process.stdin.isTTY === true;
        this.rl = readline.createInterface({
            input: process.stdin,
            output: process.stdout,
            terminal: this.isInteractive,
        });
        // Handle Ctrl+C
        this.rl.on("SIGINT", () => {
            process.stdout.write("^C\n");
            this.prompt();
        });
        // Handle close (only in interactive mode)
        if (process.stdin.isTTY) {
            this.rl.on("close", () => {
                this.running = false;
                console.log("\nGoodbye!");
                process.exit(0);
            });
        }
        this.discovery = new DiscoveryService(this.env);
    }
    syncHistory() {
        // Sync local history to Bash's BASH_HISTORY for the history command
        const envObj = this.env.getEnv();
        envObj.BASH_HISTORY = JSON.stringify(this.history);
    }
    getPrompt() {
        const cwd = this.env.getCwd();
        const home = this.env.getEnv().HOME || "/home/user";
        // Replace home with ~
        let displayCwd = cwd;
        if (cwd === home) {
            displayCwd = "~";
        }
        else if (cwd.startsWith(`${home}/`)) {
            displayCwd = `~${cwd.slice(home.length)}`;
        }
        const c = Theme.colors;
        return `${c.cyan(c.bold("ag"))}${c.dim("@")}${c.bold("kernel")}${c.dim(":")}${c.bold(c.cyan(displayCwd))}${c.dim(Theme.chars.prompt)} `;
    }
    async executeCommand(command) {
        const trimmed = command.trim();
        // Handle shell built-ins that need special treatment
        if (trimmed === "ag-info") {
            if (this.projectBrief) {
                console.log(this.discovery.getSummary(this.projectBrief));
            }
            else {
                console.log("No project knowledge discovered for this directory.");
            }
            return;
        }
        // Skip empty commands
        // Add to history
        this.history.push(trimmed);
        // Handle shell built-ins that need special treatment
        if (trimmed === "exit" || trimmed.startsWith("exit ")) {
            const parts = trimmed.split(/\s+/);
            const exitCode = parts[1] ? parseInt(parts[1], 10) : 0;
            console.log("exit");
            process.exit(exitCode);
        }
        // Sync local history with Bash's history for the history command
        this.syncHistory();
        // Execute command in Bash
        try {
            const result = await this.env.exec(trimmed);
            if (result.stdout) {
                process.stdout.write(result.stdout);
            }
            if (result.stderr) {
                process.stderr.write(Theme.colors.red(result.stderr));
            }
        }
        catch (error) {
            console.error(Theme.colors.red(`Error: ${getErrorMessage(error)}`));
        }
    }
    printWelcome() {
        Theme.printHeader("1.0.0");
        Theme.printBrandManifest();
        const stats = {
            commands: 100, // Approximate
            filesystems: 2,
            python: "Enabled",
            javascript: "Enabled",
        };
        Theme.printSuccess("Node.js", "Interactive Shell", stats);
        Theme.printPowerSuite();
    }
    prompt() {
        this.rl.question(this.getPrompt(), async (answer) => {
            if (!this.running)
                return;
            await this.executeCommand(answer);
            this.prompt();
        });
    }
    async run() {
        // Perform initial discovery scan
        this.projectBrief = await this.discovery.scan();
        if (this.isInteractive) {
            this.printWelcome();
            if (this.projectBrief) {
                console.log(Theme.colors.dim(this.discovery.getSummary(this.projectBrief)) +
                    Theme.colors.reset(""));
            }
            this.prompt();
        }
        else {
            // Non-interactive mode: read and execute line by line sequentially
            const lines = [];
            // Collect all lines first
            this.rl.on("line", (line) => {
                lines.push(line);
            });
            // Wait for all input to be read
            await new Promise((resolve) => {
                this.rl.on("close", resolve);
            });
            // Execute commands sequentially
            for (const line of lines) {
                await this.executeCommand(line);
            }
        }
    }
}
// CLI argument parsing
function parseArgs() {
    const args = process.argv.slice(2);
    // @banned-pattern-ignore: static keys only, never accessed with user input
    const options = {}; // Network disabled by default
    for (let i = 0; i < args.length; i++) {
        if (args[i] === "--cwd" && args[i + 1]) {
            options.cwd = args[++i];
        }
        else if (args[i] === "--files" && args[i + 1]) {
            const filePath = args[++i];
            try {
                const content = fs.readFileSync(filePath, "utf-8");
                options.files = JSON.parse(content);
            }
            catch (error) {
                console.error(`Error reading files from ${filePath}:`, error);
                process.exit(1);
            }
        }
        else if (args[i] === "--network") {
            options.network = true;
        }
        else if (args[i] === "--no-network") {
            options.network = false;
        }
        else if (args[i] === "--python") {
            options.python = true;
        }
        else if (args[i] === "--no-python") {
            options.python = false;
        }
        else if (args[i] === "--javascript") {
            options.javascript = true;
        }
        else if (args[i] === "--no-javascript") {
            options.javascript = false;
        }
        else if (args[i] === "--help" || args[i] === "-h") {
            console.log(`
  ag-shell — INTERACTIVE VIRTUAL BASH ENVIRONMENT
  -----------------------------------------------------------------

  Usage:
    ag-shell [options]

  Interactive shell using OverlayFS - reads from the current directory,
  writes stay in memory (copy-on-write). Perfect for safe agentic
  debugging and human-in-the-loop experimentation.

  Options:
    --cwd <path>      Initial working directory (default: /)
    --network         Enable network access (dangerouslyAllowFullInternetAccess)
    --no-network      Disable network access (default)
    --python          Enable python3 commands (default: true)
    --no-python       Disable python3 commands
    --javascript      Enable js-exec commands (default: true)
    --no-javascript   Disable js-exec commands
    -h, --help        Show this help message

  Example:
    ag-shell
    ag-shell --cwd /usr/local
    ag-shell --network
`);
            process.exit(0);
        }
    }
    return options;
}
// Main entry point
const options = parseArgs();
const shell = new VirtualShell(options);
shell.run();
