"use strict";
const test = require("node:test");
const assert = require("node:assert/strict");
const { parseCoverageTable, groupByStation } = require("../main.js").__test__;

const DOC = [
  "# Script coverage",
  "",
  "#coverage",
  "",
  "## Metadata",
  "",
  "- **Script:** `raw/sources/Webinar script.md`",
  "- **Last synced:** 2026-07-28",
  "",
  "## Coverage",
  "",
  "| Concept | Status | Station | Pinned |",
  "|---|---|---|---|",
  "| [[harness]] | covered | Tools | |",
  "| [[agentic-loops]] | partial | Process | |",
  "| [[levels-of-ai-usage]] | partial | all | |",
  "| [[connections-as-moat]] | absent | — | yes |",
].join("\n");

test("parseCoverageTable reads metadata", () => {
  const { meta } = parseCoverageTable(DOC);
  assert.equal(meta.script, "raw/sources/Webinar script.md");
  assert.equal(meta.lastSynced, "2026-07-28");
});

test("parseCoverageTable reads every data row and skips the header", () => {
  const { rows, errors } = parseCoverageTable(DOC);
  assert.equal(errors.length, 0);
  assert.equal(rows.length, 4);
  assert.deepEqual(rows.map((r) => r.concept), [
    "harness", "agentic-loops", "levels-of-ai-usage", "connections-as-moat",
  ]);
});

test("parseCoverageTable normalises stations", () => {
  const { rows } = parseCoverageTable(DOC);
  assert.deepEqual(rows[0].stations, ["Tools"]);
  assert.deepEqual(rows[2].stations, ["all"]);
  assert.deepEqual(rows[3].stations, []);
});

test("parseCoverageTable reads the pinned flag", () => {
  const { rows } = parseCoverageTable(DOC);
  assert.equal(rows[0].pinned, false);
  assert.equal(rows[3].pinned, true);
});

test("parseCoverageTable strips a wikilink alias", () => {
  const doc = "| Concept | Status | Station |\n|---|---|---|\n| [[harness\\|The harness]] | covered | Tools |";
  const { rows } = parseCoverageTable(doc);
  assert.equal(rows[0].concept, "harness");
});

test("parseCoverageTable splits a multi-station cell", () => {
  const doc = "| C | S | St |\n|---|---|---|\n| [[x]] | covered | Tools, Memory |";
  const { rows } = parseCoverageTable(doc);
  assert.deepEqual(rows[0].stations, ["Tools", "Memory"]);
});

test("parseCoverageTable rejects an invalid status instead of coercing it", () => {
  const doc = "| C | S | St |\n|---|---|---|\n| [[x]] | maybe | Tools |";
  const { rows, errors } = parseCoverageTable(doc);
  assert.equal(rows.length, 0);
  assert.equal(errors.length, 1);
  assert.match(errors[0].reason, /invalid status/);
  assert.equal(errors[0].line, 3);
});

test("parseCoverageTable reports a row with too few columns", () => {
  const doc = "| C | S | St |\n|---|---|---|\n| [[x]] | covered |";
  const { rows, errors } = parseCoverageTable(doc);
  assert.equal(rows.length, 0);
  assert.equal(errors.length, 1);
  assert.match(errors[0].reason, /at least 3 columns/);
});

test("parseCoverageTable returns empty results for a document with no table", () => {
  const { rows, errors } = parseCoverageTable("# Nothing\n\nJust prose.");
  assert.equal(rows.length, 0);
  assert.equal(errors.length, 0);
});

test("groupByStation orders all-stations first and no-station last", () => {
  const { rows } = parseCoverageTable(DOC);
  const groups = groupByStation(rows);
  assert.deepEqual(groups.map((g) => g.station), [
    "All stations", "Tools", "Process", "No station",
  ]);
  assert.equal(groups[1].rows[0].concept, "harness");
});

test("groupByStation places a multi-station row under its first station only", () => {
  const rows = [{ concept: "x", status: "covered", stations: ["Memory", "Skills"], pinned: false, line: 1 }];
  const groups = groupByStation(rows);
  assert.equal(groups.length, 1);
  assert.equal(groups[0].station, "Memory");
});
