import { describe, it, expect, beforeEach } from "vitest";
import { FileChangeStrategy } from "./file-change.strategy";
import { VerificationContext } from "../interfaces";

describe("FileChangeStrategy", () => {
  let strategy: FileChangeStrategy;
  let baseContext: VerificationContext;

  beforeEach(() => {
    strategy = new FileChangeStrategy();
    baseContext = {
      taskId: "task-1",
      workspaceId: "workspace-1",
      agentId: "agent-1",
      claimMessage: "Implemented feature",
      filesChanged: [],
      outputLogs: "",
      previousAttempts: 0,
    };
  });

  describe("verify", () => {
    it("should pass when files are changed", async () => {
      const context: VerificationContext = {
        ...baseContext,
        filesChanged: ["src/feature.ts", "src/feature.spec.ts"],
      };

      const result = await strategy.verify(context);

      expect(result.passed).toBe(true);
      expect(result.strategyName).toBe("file-change");
      expect(result.confidence).toBeGreaterThan(0);
      expect(result.issues).toHaveLength(0);
    });

    it("should fail when no files are changed", async () => {
      const context: VerificationContext = {
        ...baseContext,
        filesChanged: [],
      };

      const result = await strategy.verify(context);

      expect(result.passed).toBe(false);
      expect(result.issues).toHaveLength(1);
      expect(result.issues[0].type).toBe("missing-files");
      expect(result.issues[0].severity).toBe("error");
    });

    it("should detect TODO comments in output logs", async () => {
      const context: VerificationContext = {
        ...baseContext,
        filesChanged: ["src/feature.ts"],
        outputLogs: "File modified\nTODO: implement this later\nDone",
      };

      const result = await strategy.verify(context);

      expect(result.passed).toBe(false);
      expect(result.issues.some((i) => i.type === "incomplete-implementation")).toBe(true);
      expect(result.issues.some((i) => i.message.includes("TODO"))).toBe(true);
    });

    it("should detect FIXME comments in output logs", async () => {
      const context: VerificationContext = {
        ...baseContext,
        filesChanged: ["src/feature.ts"],
        outputLogs: "File modified\nFIXME: broken implementation\nDone",
      };

      const result = await strategy.verify(context);

      expect(result.passed).toBe(false);
      expect(result.issues.some((i) => i.type === "incomplete-implementation")).toBe(true);
      expect(result.issues.some((i) => i.message.includes("FIXME"))).toBe(true);
    });

    it("should detect placeholder implementations", async () => {
      const context: VerificationContext = {
        ...baseContext,
        filesChanged: ["src/feature.ts"],
        outputLogs: "Added placeholder implementation for now",
      };

      const result = await strategy.verify(context);

      expect(result.passed).toBe(false);
      expect(result.issues.some((i) => i.type === "incomplete-implementation")).toBe(true);
    });

    it("should detect stub implementations", async () => {
      const context: VerificationContext = {
        ...baseContext,
        filesChanged: ["src/feature.ts"],
        outputLogs: "Created stub for testing",
      };

      const result = await strategy.verify(context);

      expect(result.passed).toBe(false);
      expect(result.issues.some((i) => i.type === "incomplete-implementation")).toBe(true);
    });

    it("should reduce confidence with multiple issues", async () => {
      const context: VerificationContext = {
        ...baseContext,
        filesChanged: ["src/feature.ts"],
        outputLogs: "TODO: implement\nFIXME: broken\nPlaceholder added",
      };

      const result = await strategy.verify(context);

      expect(result.passed).toBe(false);
      expect(result.confidence).toBeLessThan(50);
      expect(result.issues.length).toBeGreaterThan(1);
    });

    it("should have high confidence when no issues found", async () => {
      const context: VerificationContext = {
        ...baseContext,
        filesChanged: ["src/feature.ts", "src/feature.spec.ts"],
        outputLogs: "Implemented feature successfully\nAll tests passing",
      };

      const result = await strategy.verify(context);

      expect(result.passed).toBe(true);
      expect(result.confidence).toBeGreaterThanOrEqual(90);
      expect(result.issues).toHaveLength(0);
    });
  });
});
