import { describe, expect, test } from "bun:test";
import { execSync } from "node:child_process";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";

import { runDisciplineReport } from "../../src/core/discipline/report.ts";

describe("runDisciplineReport", () => {
  test("end-to-end: empty log + active repo → alert text emitted", () => {
    const vault = mkdtempSync(join(tmpdir(), "o2b-disc-e2e-vault-"));
    mkdirSync(join(vault, "Brain", "log"), { recursive: true });
    writeFileSync(
      join(vault, "Brain", "_brain.yaml"),
      "schema_version: 1\ndiscipline_report:\n" +
        "  enabled: true\n  timezone: UTC\n" +
        "  watched_paths:\n    - " +
        vault +
        "/repo\n" +
        "  known_agents:\n    - '@claude-vps-agent'\n",
      "utf8",
    );

    const repo = join(vault, "repo");
    mkdirSync(repo);
    execSync("git init -q -b main", { cwd: repo });
    execSync("git config user.email t@t && git config user.name t", {
      cwd: repo,
    });
    writeFileSync(join(repo, "a.txt"), "hi\n");
    execSync("git add . && git commit -q -m c1", {
      cwd: repo,
      env: {
        ...process.env,
        GIT_COMMITTER_DATE: "2026-05-17T10:00:00Z",
        GIT_AUTHOR_DATE: "2026-05-17T10:00:00Z",
      },
    });

    const res = runDisciplineReport({
      vault,
      now: new Date("2026-05-18T01:00:00Z"),
    });
    expect(res.status).toBe("alert");
    expect(res.text).toContain("Status: alert");
    expect(res.text).toContain("1 commits");
    rmSync(vault, { recursive: true });
  });

  test("end-to-end: high structure churn emits complexity warning", () => {
    const vault = mkdtempSync(join(tmpdir(), "o2b-disc-complexity-vault-"));
    mkdirSync(join(vault, "Brain", "log"), { recursive: true });
    writeFileSync(
      join(vault, "Brain", "_brain.yaml"),
      "schema_version: 1\ndiscipline_report:\n" +
        "  enabled: true\n  timezone: UTC\n" +
        "  watched_paths:\n    - " +
        vault +
        "/repo\n" +
        "  known_agents:\n    - '@claude-vps-agent'\n",
      "utf8",
    );

    const repo = join(vault, "repo");
    mkdirSync(repo);
    execSync("git init -q -b main", { cwd: repo });
    execSync("git config user.email t@t && git config user.name t", {
      cwd: repo,
    });
    for (let index = 0; index < 12; index++) {
      writeFileSync(join(repo, `structure-${index}.md`), "metadata only\n");
    }
    execSync("git add . && git commit -q -m structure", {
      cwd: repo,
      env: {
        ...process.env,
        GIT_COMMITTER_DATE: "2026-05-17T10:00:00Z",
        GIT_AUTHOR_DATE: "2026-05-17T10:00:00Z",
      },
    });

    const res = runDisciplineReport({
      vault,
      now: new Date("2026-05-18T01:00:00Z"),
    });
    expect(res.status).toBe("alert");
    expect(res.activity?.complexity?.warning).toBe(true);
    expect(res.text).toContain("complexity");
    expect(res.text).toContain("productivity\\-trap");
    rmSync(vault, { recursive: true });
  });

  test("disabled config → result.status='disabled', empty text", () => {
    const vault = mkdtempSync(join(tmpdir(), "o2b-disc-dis-"));
    mkdirSync(join(vault, "Brain"), { recursive: true });
    writeFileSync(
      join(vault, "Brain", "_brain.yaml"),
      "schema_version: 1\ndiscipline_report:\n  enabled: false\n  timezone: UTC\n  watched_paths: []\n  known_agents: []\n",
      "utf8",
    );
    const res = runDisciplineReport({ vault, now: new Date() });
    expect(res.status).toBe("disabled");
    expect(res.text).toBe("");
    rmSync(vault, { recursive: true });
  });

  test("missing Brain config disables report for legacy bare vaults", () => {
    const vault = mkdtempSync(join(tmpdir(), "o2b-disc-missing-"));
    const res = runDisciplineReport({ vault, now: new Date() });
    expect(res.status).toBe("disabled");
    expect(res.text).toBe("");
    rmSync(vault, { recursive: true });
  });

  test("malformed Brain config is not silently disabled", () => {
    const vault = mkdtempSync(join(tmpdir(), "o2b-disc-bad-"));
    mkdirSync(join(vault, "Brain"), { recursive: true });
    writeFileSync(join(vault, "Brain", "_brain.yaml"), "not: valid: yaml\n", "utf8");
    expect(() => runDisciplineReport({ vault, now: new Date() })).toThrow();
    rmSync(vault, { recursive: true });
  });
});
