import type { ToolResultEnvelope } from "@best-agent/protocol";
import { describe, expect, it } from "vitest";
import { createShellTool } from "./shell.js";

describe("shell tool", () => {
  it("does not opt into automatic replay", () => {
    const tool = createShellTool();

    expect(tool.executionClass).toBe("external-side-effect");
    expect(tool.idempotent).toBe(false);
    expect(tool.replayPolicy).toBe("never");
  });

  it("omits multiline shell command bodies from evidence records", async () => {
    const command = "python3 - <<'PY'\n" + "secret shell payload\n".repeat(1_000) + "PY";
    const tool = createShellTool();
    const evidence = await tool.evidenceExtractor?.(
      { command, cwd: "/workspace/project", timeout_ms: 10_000 },
      "ok",
      {
        inputRawDigest: "raw-digest",
        inputStableDigest: "stable-digest",
        outcome: "success",
        summary: "ok",
        toolCallId: "item_shell" as never,
        toolName: "shell",
      } satisfies ToolResultEnvelope,
    );

    expect(JSON.stringify(evidence)).not.toContain("secret shell payload");
    expect(evidence?.[0]).toMatchObject({
      payload: {
        command: expect.stringContaining("command omitted from shell evidence"),
        commandDisplay: expect.stringContaining("command omitted from shell evidence"),
        commandForEvaluation: undefined,
        commandForProvider: undefined,
        cwd: "/workspace/project",
      },
      summary: "Shell command success: command omitted from provider evidence.",
    });
  });

  it("redacts short shell secrets from evidence records", async () => {
    const command = "curl -H 'Authorization: Bearer sk-1234567890abcdef' https://api.example.com";
    const tool = createShellTool();
    const evidence = await tool.evidenceExtractor?.(
      { command, cwd: "/workspace/project", timeout_ms: 10_000 },
      "ok",
      {
        inputRawDigest: "raw-digest",
        inputStableDigest: "stable-digest",
        outcome: "success",
        summary: "ok",
        toolCallId: "item_shell" as never,
        toolName: "shell",
      } satisfies ToolResultEnvelope,
    );

    expect(JSON.stringify(evidence)).not.toContain("sk-1234567890abcdef");
    expect(evidence?.[0]).toMatchObject({
      payload: {
        command: expect.stringContaining("Bearer [secret-redacted]"),
        commandDisplay: expect.stringContaining("Bearer [secret-redacted]"),
        commandForEvaluation: undefined,
        commandForProvider: undefined,
        cwd: "/workspace/project",
      },
      summary: "Shell command success: command omitted from provider evidence.",
    });
  });

  it("keeps unredacted non-sensitive commands for execution evidence only", async () => {
    const tokenLikePath = `/tmp/${"a".repeat(45)}/scripts/terminal-bench-benchmark.mjs`;
    const command = `node ${tokenLikePath} --n-concurrent 5`;
    const tool = createShellTool();
    const evidence = await tool.evidenceExtractor?.(
      { command, cwd: "/workspace/project", timeout_ms: 10_000 },
      "ok",
      {
        inputRawDigest: "raw-digest",
        inputStableDigest: "stable-digest",
        outcome: "success",
        summary: "ok",
        toolCallId: "item_shell" as never,
        toolName: "shell",
      } satisfies ToolResultEnvelope,
    );

    expect(evidence?.[0]?.payload.command).toContain("[long-token-redacted]");
    expect(evidence?.[0]?.payload.commandDisplay).toContain("[long-token-redacted]");
    expect(evidence?.[0]?.payload.commandForEvaluation).toBe(command);
    expect(evidence?.[0]?.payload.commandForProvider).toBeUndefined();
    expect(evidence?.[0]?.summary).toBe(
      "Shell command success: command omitted from provider evidence.",
    );
  });

  it("omits sensitive shell output from evidence records", async () => {
    const tool = createShellTool();
    const evidence = await tool.evidenceExtractor?.(
      { command: "cat .env 2>/dev/null | grep OPENAI", cwd: "/workspace/project" },
      "OPENAI_API_KEY=[redacted]",
      {
        inputRawDigest: "raw-digest",
        inputStableDigest: "stable-digest",
        outcome: "success",
        stderrSummary: "stderr secret shape",
        stdoutSummary: "OPENAI_API_KEY=[redacted]",
        summary: "ok",
        toolCallId: "item_shell" as never,
        toolName: "shell",
      } satisfies ToolResultEnvelope,
    );

    expect(evidence?.[0]).toMatchObject({
      payload: {
        indexable: false,
        sensitivity: "sensitive-redacted",
      },
      summary: "Shell command success: sensitive output omitted.",
    });
    expect(JSON.stringify(evidence)).not.toContain("OPENAI_API_KEY");
    expect(JSON.stringify(evidence)).not.toContain("stderr secret shape");
  });

  it("omits provider state shell output from evidence records", async () => {
    const tool = createShellTool();
    const evidence = await tool.evidenceExtractor?.(
      { command: "python3 -m json.tool .best-agent/cli-state.json", cwd: "/workspace/project" },
      '{"providerConfig":{"apiKey":"sk-secret"}}',
      {
        inputRawDigest: "raw-digest",
        inputStableDigest: "stable-digest",
        outcome: "success",
        stdoutSummary: '{"providerConfig":{"apiKey":"sk-secret"}}',
        summary: "ok",
        toolCallId: "item_shell" as never,
        toolName: "shell",
      } satisfies ToolResultEnvelope,
    );

    expect(evidence?.[0]).toMatchObject({
      payload: {
        indexable: false,
        sensitivity: "sensitive-redacted",
      },
      summary: "Shell command success: sensitive output omitted.",
    });
    expect(JSON.stringify(evidence)).not.toContain("sk-secret");
    expect(JSON.stringify(evidence)).not.toContain("providerConfig");
  });
});
