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

import { describe, it, expect, beforeEach } from "vitest";
import { FileReadTool } from "./read.js";

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

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

  describe("definition", () => {
    it("should have correct tool name", () => {
      expect(tool.definition.function.name).toBe("file_read");
    });

    it("should have correct definition structure for AI clients", () => {
      const def = tool.definition;
      expect(def.type).toBe("function");
      expect(def.function).toBeDefined();
      expect(def.function.name).toBe("file_read");
      expect(def.function.description).toBeDefined();
      expect(def.function.parameters).toBeDefined();
      const params = def.function.parameters as any;
      expect(params.type).toBe("object");
      expect(params.properties).toBeDefined();
      expect(params.properties.path).toBeDefined();
      expect(params.required).toContain("path");
    });
  });

  describe("execute", () => {
    it("should return error for missing path", async () => {
      const result = await tool.execute({ session: mockSession }, { path: "" });

      expect(result).toContain("MISSING_PARAMETER");
      expect(result).toContain("File path must not be empty");
    });

    it("should return error for non-existent file", async () => {
      const result = await tool.execute(
        { session: mockSession },
        { path: "non/existent/file.txt" },
      );

      expect(result).toContain("NOT_FOUND");
      expect(result).toContain("File not found");
    });

    it("should successfully read README.md", async () => {
      const result = await tool.execute(
        { session: mockSession },
        { path: "README.md" },
      );

      // Result is now plain text with header metadata
      expect(result).toContain("PATH: README.md");
      expect(result).toContain("TOTAL LINES:");
      expect(result).toContain("LINES SHOWN:");
      expect(result).toContain("FILE OPERATION: read");
      expect(result).toContain("Gadget Code");
    });

    it("should read file with line numbers", async () => {
      const result = await tool.execute(
        { session: mockSession },
        { path: "README.md" },
      );

      // Result is plain text - content is after the "---" separator
      expect(result).toContain("Gadget Code");

      const lines = result.split("\n");
      const firstContentLine = lines.find((l: string) =>
        l.includes("Gadget Code"),
      );
      expect(firstContentLine).toBeDefined();
      if (firstContentLine) {
        expect(firstContentLine).toMatch(/^\d+:/);
      }
    });

    it("should respect line range parameters", async () => {
      const result = await tool.execute(
        { session: mockSession },
        { path: "README.md", startLine: 1, endLine: 3 },
      );

      // Result is plain text - check for line range in output
      expect(result).toContain("lines 1-3");
      const lines = result.split("\n").filter((l: string) => l.match(/^\d+: /));
      expect(lines.length).toBeLessThanOrEqual(3);
    });
  });

  describe("response format for AI clients", () => {
    it("should return a string that can be used in message content", async () => {
      const result = await tool.execute(
        { session: mockSession },
        { path: "README.md" },
      );

      expect(typeof result).toBe("string");
      expect(result.length).toBeGreaterThan(0);
    });

    it("should return plain text with header metadata", async () => {
      const result = await tool.execute(
        { session: mockSession },
        { path: "README.md" },
      );

      // Verify plain text format with header
      expect(result).toMatch(/^PATH:/m);
      expect(result).toContain("TOTAL LINES:");
      expect(result).toContain("LINES SHOWN:");
      expect(result).toContain("FILE OPERATION: read");
      expect(result).toContain("---");
    });
  });
});
