import { readFileSync, readdirSync } from "node:fs";
import { describe, expect, it } from "vitest";
import { unsafeOpaqueId, type ChangeSetId } from "@awp/contracts";
import { trustedPublicationTargetRef } from "../../packages/providers/vcs-github/src/index.js";

function sourceFiles(directory: string): readonly string[] {
  return readdirSync(directory, { withFileTypes: true }).flatMap((entry) => {
    const path = `${directory}/${entry.name}`;
    if (entry.isDirectory()) return sourceFiles(path);
    return entry.isFile() && /\.(?:ts|js)$/u.test(entry.name) ? [path] : [];
  });
}

describe("I1 VCS pain invariants", () => {
  it("no-git-vocabulary-in-user-surfaces", () => {
    const userSurface = sourceFiles("apps/web/src")
      .filter((file) => /\/(?:render-[^/]+|shell|app|approved-live|live)\.ts$/u.test(file))
      .map((file) => readFileSync(file, "utf8"))
      .join("\n")
      .toLowerCase();
    for (const term of [
      "rebase",
      "force-push",
      "upstream",
      "detached head",
      "conflict marker",
      "cherry-pick",
      "stash",
    ]) {
      expect(userSurface, `owner UI leaked VCS mechanic: ${term}`).not.toContain(term);
    }
  });

  it("no-approval-of-git-kind", () => {
    const application = sourceFiles("packages/application/src")
      .map((file) => readFileSync(file, "utf8"))
      .join("\n");
    expect(application).not.toMatch(/tx\.approvals|approvals\.(?:insert|update)/u);
    const attention = readFileSync("apps/web/src/approved-live.ts", "utf8");
    expect(attention).not.toMatch(/humanActionRequired:\s*true/u);
  });

  it("no-git-operation-discards-uncollected-wip", () => {
    const execution = readFileSync("packages/application/src/execution.ts", "utf8");
    expect(execution).toContain(
      "Repository correction refuses to run without the collected exact-candidate Workspace checkpoint",
    );
    expect(execution).toContain("sourceWorkspace.checkpointCollectedAt === undefined");
    expect(execution).toContain("sourceWorkspace.checkpointDigest !== changeSet.candidateDigest");
    expect(execution).toContain("replaceCompute");
    expect(execution).not.toContain("git reset --hard");
    expect(execution).not.toContain("git clean -fd");
  });

  it("branch-strategy-is-deterministic", () => {
    const id = unsafeOpaqueId<ChangeSetId>("changeset:deterministic");
    const first = trustedPublicationTargetRef(id);
    const second = trustedPublicationTargetRef(id);
    expect(first).toBe(second);
    expect(first).toBe("refs/heads/awp/changeset-deterministic");
    expect(trustedPublicationTargetRef(unsafeOpaqueId<ChangeSetId>("changeset:other"))).not.toBe(
      first,
    );
  });
});
