import { describe, it, expect } from "vitest";
import {
  moduleCategories,
  appComposeCategories,
  moduleTestCaseCategories,
  appTestCaseCategories,
  buildCheckTargets,
} from "./discovery";

describe("moduleCategories", () => {
  it("produces command/model/query categories with correct patterns", () => {
    const cats = moduleCategories("modules");
    expect(cats).toHaveLength(3);

    const command = cats.find((c) => c.name === "command")!;
    expect(command.sourcePattern).toBe("modules/*/command/*.ts");
    expect(command.docPattern).toBe("modules/*/docs/commands/*.md");
    expect(command.exclusions).toEqual([/\.test\.ts$/, /\.generated\.ts$/]);

    const model = cats.find((c) => c.name === "model")!;
    expect(model.sourcePattern).toBe("modules/*/db/*.ts");
    expect(model.docPattern).toBe("modules/*/docs/models/*.md");

    const query = cats.find((c) => c.name === "query")!;
    expect(query.sourcePattern).toBe("modules/*/query/*.ts");
    expect(query.docPattern).toBe("modules/*/docs/queries/*.md");
  });
});

describe("appComposeCategories", () => {
  it("produces resolver category", () => {
    const cats = appComposeCategories("apps/myapp");
    expect(cats).toHaveLength(1);
    expect(cats[0].name).toBe("resolver");
    expect(cats[0].docPattern).toBe("apps/myapp/docs/resolver/*.md");
  });
});

describe("moduleTestCaseCategories", () => {
  it("produces command and query test case categories", () => {
    const cats = moduleTestCaseCategories("modules");
    expect(cats).toHaveLength(2);
    expect(cats[0].testDir).toBe("command");
    expect(cats[1].testDir).toBe("query");
  });
});

describe("appTestCaseCategories", () => {
  it("produces story test case category with correct pattern", () => {
    const cats = appTestCaseCategories("apps");
    expect(cats.name).toBe("story-test-case");
    expect(cats.docPattern).toBe("apps/*/docs/business-flow/*/story/*.md");
    expect(cats.testDir).toBe("backend/src/tests/stories");
  });
});

describe("buildCheckTargets", () => {
  it("builds module check targets", () => {
    const targets = buildCheckTargets({ modulesRoot: "modules" });
    expect(targets).toHaveLength(5);
    expect(targets.map((t) => t.schemaKey)).toEqual([
      "feature",
      "command",
      "model",
      "query",
      "module",
    ]);
    expect(targets[0].glob).toBe("modules/[a-zA-Z]*/docs/features/*.md");
  });

  it("builds app check targets", () => {
    const targets = buildCheckTargets({ appRoot: "apps/myapp" });
    expect(targets).toHaveLength(6);
    expect(targets.map((t) => t.schemaKey)).toContain("screen");
    expect(targets.find((t) => t.schemaKey === "screen")!.glob).toBe("apps/myapp/docs/screen/*.md");
  });

  it("builds both when both roots provided", () => {
    const targets = buildCheckTargets({ modulesRoot: "modules", appRoot: "apps/myapp" });
    expect(targets).toHaveLength(11);
  });
});
