/**
 * Reference: agentOS VM as a sandbox backend for Flue.
 *
 * This script demonstrates the core idea behind a Flue sandbox adapter that
 * delegates file/shell operations to an agentOS VM. It does NOT wire into the
 * Flue agent yet — it proves the primitives work end-to-end so you can see
 * exactly how the adapter will map calls.
 *
 * Run:  bun --env-file=../../.env packages/agents/scripts/agentos-sandbox-ref.ts
 *
 * Architecture:
 *
 *   Flue agent (host)                      agentOS VM (isolated Wasm+V8)
 *   ┌─────────────────────┐                ┌──────────────────────┐
 *   │  defineAgent(...)   │                │  Linux-like sandbox   │
 *   │    sandbox: agentOs()│── readFile ──► │  persistent FS        │
 *   │                     │── writeFile ─► │  shell (sh, coreutils)│
 *   │                     │── exec ──────► │  ~6ms cold start      │
 *   └─────────────────────┘                └──────────────────────┘
 *
 * The Flue SandboxApi maps 1:1 to AgentOs methods:
 *
 *   Flue SandboxApi              AgentOs (core SDK)
 *   ─────────────────────────    ──────────────────────────
 *   readFile(path)               vm.readFile(path)
 *   readFileBuffer(path)         vm.readFile(path)
 *   writeFile(path, content)     vm.writeFile(path, content)
 *   stat(path)                   vm.stat(path)
 *   readdir(path)                vm.readdir(path)
 *   exists(path)                 vm.exists(path)
 *   mkdir(path)                  vm.mkdir(path)
 *   rm(path)                     vm.remove(path)
 *   exec(command, opts)          vm.exec(command, opts)
 */

import { AgentOs } from "@rivet-dev/agentos-core";
import type { VirtualStat } from "@rivet-dev/agentos-core";

const formatStat = (stat: VirtualStat): string =>
  JSON.stringify({
    isDirectory: stat.isDirectory,
    isSymbolicLink: stat.isSymbolicLink,
    mtime: new Date(stat.mtimeMs).toISOString(),
    size: stat.size,
  });

const main = async () => {
  console.log("=== Booting agentOS VM ===\n");

  // AgentOs.create() boots a local VM with the default software bundle
  // (sh + coreutils). The VM sleeps when idle and wakes on the next action.
  const vm = await AgentOs.create();
  console.log("VM booted.\n");

  // ── File operations ──────────────────────────────────────────────

  console.log("=== writeFile ===");
  await vm.writeFile("/workspace/hello.txt", "Hello from agentOS VM!");
  console.log("wrote /workspace/hello.txt\n");

  console.log("=== readFile ===");
  const content = await vm.readFile("/workspace/hello.txt");
  console.log("content:", new TextDecoder().decode(content), "\n");

  console.log("=== stat ===");
  const stat = await vm.stat("/workspace/hello.txt");
  console.log("stat:", formatStat(stat), "\n");

  console.log("=== exists ===");
  console.log(
    "exists /workspace/hello.txt:",
    await vm.exists("/workspace/hello.txt")
  );
  console.log(
    "exists /workspace/nope.txt:",
    await vm.exists("/workspace/nope.txt"),
    "\n"
  );

  console.log("=== mkdir + readdir ===");
  await vm.mkdir("/workspace/src", { recursive: true });
  await vm.writeFile("/workspace/src/a.ts", "export const a = 1;");
  await vm.writeFile("/workspace/src/b.ts", "export const b = 2;");
  console.log(
    "readdir /workspace/src:",
    await vm.readdir("/workspace/src"),
    "\n"
  );

  // ── Shell exec ───────────────────────────────────────────────────

  console.log("=== exec: echo ===");
  const echoResult = await vm.exec("echo 'shell works!'");
  console.log(
    "stdout:",
    echoResult.stdout.trim(),
    `(exit ${echoResult.exitCode})\n`
  );

  console.log("=== exec: pipe + coreutils ===");
  const pipeResult = await vm.exec("echo 'hello world' | tr a-z A-Z | wc -w");
  console.log(
    "stdout:",
    pipeResult.stdout.trim(),
    `(exit ${pipeResult.exitCode})\n`
  );

  console.log("=== exec: with cwd + env ===");
  await vm.mkdir("/workspace/project", { recursive: true });
  await vm.writeFile("/workspace/project/file.txt", "data");
  const cwdResult = await vm.exec("pwd && ls", {
    cwd: "/workspace/project",
    env: { CUSTOM_VAR: "from-env" },
  });
  console.log(
    "stdout:",
    cwdResult.stdout.trim(),
    `(exit ${cwdResult.exitCode})\n`
  );

  // ── Remove ───────────────────────────────────────────────────────

  console.log("=== remove ===");
  await vm.remove("/workspace/src/b.ts");
  console.log(
    "after remove, readdir:",
    await vm.readdir("/workspace/src"),
    "\n"
  );

  // ── Cleanup ──────────────────────────────────────────────────────

  await vm.dispose();
  console.log("=== VM disposed. All primitives work. ===");
};

try {
  await main();
} catch (error) {
  console.error(error);
  process.exit(1);
}
