import { describe, it, expect, beforeEach, afterEach } from "vitest";
import { join } from "path";
import { mkdir, writeFile, rm } from "fs/promises";
import { tmpdir } from "os";
import { detectAIPatterns, patternMatchesToIndicators, scanDirectoryForAIPatterns, calculateAILikelihood, aggregateByFile, } from "../../../scanners/ai-code/ai-detector.js";
describe("ai-detector", () => {
    let testDir;
    beforeEach(async () => {
        testDir = join(tmpdir(), `ai-detector-test-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`);
        await mkdir(testDir, { recursive: true });
    });
    afterEach(async () => {
        await rm(testDir, { recursive: true, force: true });
    });
    describe("detectAIPatterns", () => {
        it("detects AI generation comments", async () => {
            const content = `
// Generated by ChatGPT
function test() {
  return true;
}
`;
            const filePath = join(testDir, "test.ts");
            await writeFile(filePath, content);
            const matches = await detectAIPatterns(filePath);
            expect(matches.length).toBeGreaterThan(0);
            expect(matches[0].pattern).toBe("ai-comment-generated");
            expect(matches[0].confidence).toBe("high");
        });
        it("detects copilot suggestions", async () => {
            const content = `
// Copilot suggestion
const x = 1;
`;
            const filePath = join(testDir, "copilot.ts");
            await writeFile(filePath, content);
            const matches = await detectAIPatterns(filePath);
            expect(matches.length).toBeGreaterThan(0);
            expect(matches[0].pattern).toBe("ai-comment-assistant");
        });
        it("detects TODO placeholders", async () => {
            const content = `
function example() {
  // TODO: implement this logic here
  return null;
}
`;
            const filePath = join(testDir, "todo.ts");
            await writeFile(filePath, content);
            const matches = await detectAIPatterns(filePath);
            expect(matches.length).toBeGreaterThan(0);
            expect(matches.some((m) => m.pattern === "todo-placeholder")).toBe(true);
        });
        it("detects cursor metadata", async () => {
            const content = `
// @cursor-ai generated
const y = 2;
`;
            const filePath = join(testDir, "cursor.ts");
            await writeFile(filePath, content);
            const matches = await detectAIPatterns(filePath);
            expect(matches.length).toBeGreaterThan(0);
            expect(matches[0].pattern).toBe("cursor-metadata");
            expect(matches[0].confidence).toBe("high");
        });
        it("returns empty array for clean code", async () => {
            const content = `
function add(a: number, b: number): number {
  return a + b;
}
`;
            const filePath = join(testDir, "clean.ts");
            await writeFile(filePath, content);
            const matches = await detectAIPatterns(filePath);
            expect(matches).toEqual([]);
        });
    });
    describe("patternMatchesToIndicators", () => {
        it("converts pattern matches to indicators", () => {
            const matches = [
                {
                    pattern: "ai-comment-generated",
                    file: "/test.ts",
                    line: 1,
                    match: "// Generated by ChatGPT",
                    confidence: "high",
                },
            ];
            const indicators = patternMatchesToIndicators(matches);
            expect(indicators.length).toBe(1);
            expect(indicators[0].type).toBe("comment");
            expect(indicators[0].confidence).toBe("high");
            expect(indicators[0].location.file).toBe("/test.ts");
            expect(indicators[0].location.line).toBe(1);
        });
    });
    describe("scanDirectoryForAIPatterns", () => {
        it("scans multiple files", async () => {
            await writeFile(join(testDir, "a.ts"), "// Generated by AI\nconst a = 1;");
            await writeFile(join(testDir, "b.ts"), "const b = 2;");
            await writeFile(join(testDir, "c.ts"), "// @copilot-generated\nconst c = 3;");
            const result = await scanDirectoryForAIPatterns(testDir);
            expect(result.files).toBe(3);
            expect(result.matches.length).toBe(2);
            expect(result.indicators.length).toBe(2);
        });
        it("respects exclude patterns", async () => {
            await mkdir(join(testDir, "node_modules"), { recursive: true });
            await writeFile(join(testDir, "node_modules", "dep.ts"), "// Generated by AI");
            await writeFile(join(testDir, "main.ts"), "const x = 1;");
            const result = await scanDirectoryForAIPatterns(testDir);
            expect(result.files).toBe(1);
            expect(result.matches.length).toBe(0);
        });
    });
    describe("calculateAILikelihood", () => {
        it("returns 0 for empty indicators", () => {
            expect(calculateAILikelihood([])).toBe(0);
        });
        it("scores high confidence indicators higher", () => {
            const highIndicators = [
                {
                    type: "comment",
                    location: { file: "a.ts", line: 1 },
                    description: "AI comment",
                    confidence: "high",
                    evidence: "test",
                },
            ];
            const lowIndicators = [
                {
                    type: "pattern",
                    location: { file: "b.ts", line: 1 },
                    description: "Low pattern",
                    confidence: "low",
                    evidence: "test",
                },
            ];
            expect(calculateAILikelihood(highIndicators)).toBeGreaterThan(calculateAILikelihood(lowIndicators));
        });
        it("caps at 100", () => {
            const manyIndicators = Array(10).fill({
                type: "comment",
                location: { file: "a.ts", line: 1 },
                description: "AI",
                confidence: "high",
                evidence: "test",
            });
            expect(calculateAILikelihood(manyIndicators)).toBe(100);
        });
    });
    describe("aggregateByFile", () => {
        it("groups indicators by file", () => {
            const indicators = [
                {
                    type: "comment",
                    location: { file: "a.ts", line: 1 },
                    description: "AI",
                    confidence: "high",
                    evidence: "test",
                },
                {
                    type: "comment",
                    location: { file: "a.ts", line: 5 },
                    description: "AI 2",
                    confidence: "medium",
                    evidence: "test",
                },
                {
                    type: "pattern",
                    location: { file: "b.ts", line: 1 },
                    description: "Pattern",
                    confidence: "low",
                    evidence: "test",
                },
            ];
            const result = aggregateByFile(indicators);
            expect(result.size).toBe(2);
            const aFile = result.get("a.ts");
            expect(aFile?.count).toBe(2);
            expect(aFile?.maxConfidence).toBe("high");
            const bFile = result.get("b.ts");
            expect(bFile?.count).toBe(1);
            expect(bFile?.maxConfidence).toBe("low");
        });
    });
});
//# sourceMappingURL=ai-detector.test.js.map