import { describe, it, expect, vi } from "vitest";
import { runFileChecksumVerifier } from "./run";
import type { ToolContext } from "../../core/plugins/plugin-types";

describe("File Checksum Verifier Plugin", () => {
  const mockContext: ToolContext = {
    signal: new AbortController().signal,
    reportProgress: vi.fn(),
    logger: {
      info: vi.fn(),
      warn: vi.fn(),
      error: vi.fn(),
    },
  };

  const textFile = new File(
    [new TextEncoder().encode("hello world")],
    "test.txt",
    { type: "text/plain" }
  );

  const helloWorldSha256 = "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9";

  it("should calculate SHA-256 checksum and verify successfully", async () => {
    const result = await runFileChecksumVerifier(
      {
        values: {
          files: { files: [textFile] },
          expectedChecksum: { text: helloWorldSha256 },
        },
      },
      { algorithm: "SHA-256" },
      mockContext
    );

    expect(result.type).toBe("table");
    if (result.type === "table") {
      expect(result.columns).toEqual(["File Name", "Size", "Computed Hash", "Expected Hash", "Status"]);
      expect(result.rows).toHaveLength(1);
      expect(result.rows[0][0]).toBe("test.txt");
      expect(result.rows[0][1]).toBe("11 B");
      expect(result.rows[0][2]).toBe(helloWorldSha256);
      expect(result.rows[0][3]).toBe(helloWorldSha256);
      expect(result.rows[0][4]).toBe("✅ Match");
    }
  });

  it("should detect checksum mismatch", async () => {
    const result = await runFileChecksumVerifier(
      {
        values: {
          files: { files: [textFile] },
          expectedChecksum: { text: "wrongchecksum" },
        },
      },
      { algorithm: "SHA-256" },
      mockContext
    );

    if (result.type === "table") {
      expect(result.rows[0][4]).toBe("❌ Mismatch");
    }
  });

  it("should run with no expected checksum and mark status as N/A", async () => {
    const result = await runFileChecksumVerifier(
      {
        values: {
          files: { files: [textFile] },
        },
      },
      { algorithm: "SHA-256" },
      mockContext
    );

    if (result.type === "table") {
      expect(result.rows[0][3]).toBe("(none)");
      expect(result.rows[0][4]).toBe("N/A");
    }
  });

  it("should throw error if no files are supplied", async () => {
    await expect(
      runFileChecksumVerifier({}, { algorithm: "SHA-256" }, mockContext)
    ).rejects.toThrow("Please select at least one file to verify.");
  });
});
