/**
 * PR-A Baseline Test 05: exec Tool Current Behavior
 * Verifies: shell command execution returns stdout/stderr/exitCode correctly
 * Freezes: exec tool contract
 */

import { describe, it } from "node:test";
import assert from "node:assert";
import { execSync, spawnSync } from "node:child_process";
import { homedir } from "node:os";
import { join } from "node:path";

const GATEWAY_URL = "http://127.0.0.1:18789";

describe("test-05: exec Tool Baseline", () => {
  it("05.01 - local shell execution works (node child_process)", () => {
    const result = spawnSync("echo", ["hello"], {
      encoding: "utf8",
      timeout: 5000,
    });
    console.log("[BASELINE] echo hello stdout:", JSON.stringify(result.stdout.trim()));
    console.log("[BASELINE] echo hello stderr:", JSON.stringify(result.stderr));
    console.log("[BASELINE] echo hello status:", result.status);
    assert.equal(result.stdout.trim(), "hello", "echo must output hello");
    assert.equal(result.status, 0, "exit code must be 0");
  });

  it("05.02 - shell error exit codes are preserved", () => {
    const result = spawnSync("sh", ["-c", "exit 42"], {
      encoding: "utf8",
      timeout: 5000,
    });
    console.log("[BASELINE] exit 42 status:", result.status);
    assert.equal(result.status, 42, "exit code must be preserved exactly");
  });

  it("05.03 - shell stderr is captured separately", () => {
    const result = spawnSync("sh", ["-c", "echo stdout-text && echo stderr-text >&2"], {
      encoding: "utf8",
      timeout: 5000,
    });
    console.log("[BASELINE] stdout:", JSON.stringify(result.stdout.trim()));
    console.log("[BASELINE] stderr:", JSON.stringify(result.stderr.trim()));
    assert.ok(result.stdout.includes("stdout-text"), "stdout must contain message");
    assert.ok(result.stderr.includes("stderr-text"), "stderr must contain message");
  });

  it("05.04 - shell output encoding is UTF-8", () => {
    const result = spawnSync("sh", ["-c", "echo 你好世界"], {
      encoding: "utf8",
      timeout: 5000,
    });
    console.log("[BASELINE] UTF-8 output:", JSON.stringify(result.stdout.trim()));
    assert.ok(result.stdout.includes("你好世界"), "UTF-8 must be preserved");
  });

  it("05.05 - shell timeout kills process", () => {
    const start = Date.now();
    const result = spawnSync("sleep", ["10"], {
      encoding: "utf8",
      timeout: 2000, // 2 second timeout
    });
    const elapsed = Date.now() - start;
    console.log("[BASELINE] sleep 10 timeout: elapsed=%dms, killed=%s",
      elapsed, result.signal || "none");
    // Process should be killed by timeout
    assert.ok(result.signal === "SIGTERM" || result.status !== 0 || elapsed < 10000,
      "long-running process must be terminated by timeout");
  });

  it("05.06 - exec tool: binary output handling", () => {
    // Create a null-byte test
    const result = spawnSync("printf", ["\\x00hello\\x00"], {
      encoding: "buffer",
      timeout: 5000,
    });
    console.log("[BASELINE] binary stdout length:", result.stdout.length);
    console.log("[BASELINE] binary stdout bytes:", 
      Array.from(result.stdout.slice(0, 10)).map(b => '0x' + b.toString(16)).join(' '));
    assert.ok(result.stdout.includes(0x68), "output must contain 'h' (0x68)");
  });

  it("05.07 - exec tool: large output handled", () => {
    // Generate 10KB of output
    const result = spawnSync("sh", ["-c", "yes head | head -1000"], {
      encoding: "utf8",
      timeout: 5000,
      maxBuffer: 1024 * 1024,
    });
    const lines = result.stdout.trim().split("\n").length;
    console.log("[BASELINE] large output: lines=%d, bytes=%d", lines, result.stdout.length);
    assert.ok(lines > 100, "large output must be captured");
  });
});
