import path from "node:path";
import { describe, expect, it } from "vitest";
import {
  buildGroupedTestComparison,
  buildGroupedTestReport,
  renderGroupedTestComparison,
  resolveGroupKey,
  resolveTestArea,
} from "../../scripts/lib/test-group-report.mjs";
import {
  parseTestGroupReportArgs,
  resolveReportArtifactDirs,
} from "../../scripts/test-group-report.mjs";

describe("scripts/test-group-report grouping", () => {
  it("groups repo files by stable product area", () => {
    expect(resolveTestArea("extensions/discord/src/send.test.ts")).toBe("extensions/discord");
    expect(resolveTestArea("src/commands/agent.test.ts")).toBe("src/commands");
    expect(resolveTestArea("packages/plugin-sdk/src/index.test.ts")).toBe("packages/plugin-sdk");
    expect(resolveTestArea("ui/src/ui/views/chat.test.ts")).toBe("ui/views");
    expect(resolveTestArea("test/scripts/test-group-report.test.ts")).toBe("test/scripts");
  });

  it("supports folder and top-level grouping modes", () => {
    expect(resolveGroupKey("src/commands/agent.test.ts", "folder")).toBe("src/commands");
    expect(resolveGroupKey("extensions/browser/src/browser/pw.test.ts", "folder")).toBe(
      "extensions/browser/src",
    );
    expect(resolveGroupKey("extensions/browser/src/browser/pw.test.ts", "top")).toBe("extensions");
  });
});

describe("scripts/test-group-report aggregation", () => {
  it("aggregates file durations by group and config", () => {
    const report = buildGroupedTestReport({
      groupBy: "area",
      reports: [
        {
          config: "test/vitest/vitest.commands.config.ts",
          report: {
            testResults: [
              {
                name: path.join(process.cwd(), "src", "commands", "agent.test.ts"),
                startTime: 100,
                endTime: 700,
                assertionResults: [{}, {}],
              },
              {
                name: path.join(process.cwd(), "extensions", "discord", "src", "send.test.ts"),
                startTime: 200,
                endTime: 450,
                assertionResults: [{}],
              },
            ],
          },
        },
      ],
    });

    expect(report.totals).toEqual({ durationMs: 850, fileCount: 2, testCount: 3 });
    expect(report.groups.map((group) => [group.key, group.durationMs])).toEqual([
      ["src/commands", 600],
      ["extensions/discord", 250],
    ]);
    expect(report.configs).toMatchObject([
      {
        key: "commands",
        durationMs: 850,
        fileCount: 2,
        testCount: 3,
      },
    ]);
  });
});

describe("scripts/test-group-report comparison", () => {
  it("compares grouped reports by group, file, config, and run metrics", () => {
    const comparison = buildGroupedTestComparison({
      beforePath: "before.json",
      afterPath: "after.json",
      before: {
        groupBy: "area",
        totals: { durationMs: 1000, fileCount: 2, testCount: 4 },
        groups: [
          { key: "src/commands", durationMs: 700, fileCount: 1, testCount: 2 },
          { key: "extensions/discord", durationMs: 300, fileCount: 1, testCount: 2 },
        ],
        configs: [{ key: "commands", durationMs: 1000, fileCount: 2, testCount: 4 }],
        topFiles: [
          {
            config: "commands",
            file: "src/commands/agent.test.ts",
            group: "src/commands",
            durationMs: 700,
            testCount: 2,
          },
          {
            config: "commands",
            file: "extensions/discord/src/send.test.ts",
            group: "extensions/discord",
            durationMs: 300,
            testCount: 2,
          },
        ],
        runs: [
          {
            config: "test/vitest/vitest.commands.config.ts",
            elapsedMs: 2000,
            maxRssBytes: 1024 * 1024 * 100,
            status: 0,
          },
        ],
      },
      after: {
        groupBy: "area",
        totals: { durationMs: 900, fileCount: 2, testCount: 5 },
        groups: [{ key: "src/commands", durationMs: 900, fileCount: 2, testCount: 5 }],
        configs: [{ key: "commands", durationMs: 900, fileCount: 2, testCount: 5 }],
        topFiles: [
          {
            config: "commands",
            file: "src/commands/agent.test.ts",
            group: "src/commands",
            durationMs: 800,
            testCount: 3,
          },
          {
            config: "commands",
            file: "src/commands/new.test.ts",
            group: "src/commands",
            durationMs: 100,
            testCount: 2,
          },
        ],
        runs: [
          {
            config: "test/vitest/vitest.commands.config.ts",
            elapsedMs: 1800,
            maxRssBytes: 1024 * 1024 * 80,
            status: 0,
          },
        ],
      },
    });

    expect(comparison.totals.delta).toEqual({ durationMs: -100, fileCount: 0, testCount: 1 });
    expect(comparison.groups.find((group) => group.key === "src/commands")).toMatchObject({
      delta: { durationMs: 200, fileCount: 1, testCount: 3 },
    });
    expect(
      comparison.files.find((file) => file.file === "extensions/discord/src/send.test.ts"),
    ).toMatchObject({
      status: "removed",
      delta: { durationMs: -300, testCount: -2 },
    });
    expect(comparison.runs[0]).toMatchObject({
      key: "commands",
      delta: { elapsedMs: -200, maxRssBytes: -1024 * 1024 * 20 },
    });

    expect(renderGroupedTestComparison(comparison, { limit: 2, topFiles: 2 })).toContain(
      "Top group regressions",
    );
  });
});

describe("scripts/test-group-report arg parsing", () => {
  it("parses repeatable config and passthrough args", () => {
    expect(
      parseTestGroupReportArgs([
        "--config",
        "a.ts",
        "--config",
        "b.ts",
        "--group-by",
        "folder",
        "--allow-failures",
        "--",
        "--maxWorkers=1",
      ]),
    ).toMatchObject({
      allowFailures: true,
      configs: ["a.ts", "b.ts"],
      groupBy: "folder",
      vitestArgs: ["--maxWorkers=1"],
    });
  });

  it("parses compare mode", () => {
    expect(
      parseTestGroupReportArgs([
        "--compare",
        "before.json",
        "after.json",
        "--limit",
        "5",
        "--top-files",
        "3",
      ]),
    ).toMatchObject({
      compare: { before: "before.json", after: "after.json" },
      limit: 5,
      topFiles: 3,
    });
  });
});

describe("scripts/test-group-report artifact paths", () => {
  it("keeps raw Vitest reports scoped to the output file stem", () => {
    expect(resolveReportArtifactDirs(".artifacts/test-perf/baseline-before.json")).toEqual({
      reportDir: path.join(".artifacts", "test-perf", "baseline-before", "vitest-json"),
      logDir: path.join(".artifacts", "test-perf", "baseline-before", "logs"),
    });
  });
});
