// src/tools/file/shell.test.ts
// Copyright (C) 2025 DTP Technologies, LLC
// All Rights Reserved

import { describe, it, expect, beforeEach } from "vitest";
import ShellExecTool from "./shell.js";

describe("ShellExecTool", () => {
  const tool = ShellExecTool;
  let mockSession: any;

  beforeEach(() => {
    mockSession = {
      _id: "test-session-id",
      user: "test-user-id",
    };
  });

  it("should have correct tool definition", () => {
    expect(tool.name).toBe("ShellExecTool");
    expect(tool.slug).toBe("shell-exec");
    expect(tool.definition.type).toBe("function");
    expect(tool.definition.function.name).toBe("shell_exec");
  });

  it("should have correct metadata", () => {
    expect(tool.metadata.name).toBe("shell_exec");
    expect(tool.metadata.category).toBe("file");
    expect(tool.metadata.tags).toContain("shell");
  });

  it("should return error for empty command", async () => {
    const result = await tool.execute(
      { session: mockSession },
      { command: "" },
    );
    expect(result).toContain("error");
    expect(result).toContain("MISSING_PARAMETER");
  });

  it("should return error for whitespace-only command", async () => {
    const result = await tool.execute(
      { session: mockSession },
      { command: "   " },
    );
    expect(result).toContain("error");
    expect(result).toContain("MISSING_PARAMETER");
  });

  it("should execute simple command successfully", async () => {
    const result = await tool.execute(
      { session: mockSession },
      { command: "echo hello" },
    );
    expect(result).toContain("COMMAND: echo hello");
    expect(result).toContain("EXIT CODE: 0");
    expect(result).toContain("---[stdout]");
    expect(result).toContain("hello");
    expect(result).toContain("---[stderr]");
  });

  it("should return plain text format in message field", async () => {
    const result = await tool.execute(
      { session: mockSession },
      { command: "echo test" },
    );
    // The message field should contain plain text format
    expect(result).toContain('"message":');
    // The message should contain plain text headers (not JSON-escaped in the message value)
    expect(result).toContain("COMMAND: echo test");
    expect(result).toContain("EXIT CODE: 0");
  });

  it("should include stderr when command fails", async () => {
    const result = await tool.execute(
      { session: mockSession },
      { command: "ls /nonexistent/path/that/does/not/exist" },
    );
    expect(result).toContain("COMMAND:");
    expect(result).toContain("---[stderr]");
  });

  it("should handle command with both stdout and stderr", async () => {
    const result = await tool.execute(
      { session: mockSession },
      { command: "sh -c 'echo stdout; echo stderr >&2'" },
    );
    expect(result).toContain("---[stdout]");
    expect(result).toContain("---[stderr]");
    expect(result).toContain("stdout");
    expect(result).toContain("stderr");
  });

  it("should preserve whitespace in output", async () => {
    const result = await tool.execute(
      { session: mockSession },
      { command: "echo '  spaces  '" },
    );
    // The output should preserve the spaces
    expect(result).toContain("spaces");
  });

  it("should show N/A for empty stdout", async () => {
    // Commands that produce no stdout
    const result = await tool.execute(
      { session: mockSession },
      { command: "true" },
    );
    expect(result).toContain("---[stdout]");
    // Should have the marker even if empty
  });

  it("should include exit code in output", async () => {
    const result = await tool.execute(
      { session: mockSession },
      { command: "echo test" },
    );
    expect(result).toMatch(/EXIT CODE: \d+/);
  });
});
