import { expect, test } from "bun:test";
import { readdirSync, readFileSync } from "node:fs";
import { join } from "node:path";

function outputBlocks(source: string): string[] {
  const blocks: string[] = [];
  for (const match of source.matchAll(/\boutputs\s*\{/g)) {
    const brace = source.indexOf("{", match.index);
    let depth = 0;
    let quote = "";
    for (let index = brace; index < source.length; index++) {
      const char = source[index]!;
      if (quote) {
        if (char === "\\") index++;
        else if (char === quote) quote = "";
        continue;
      }
      if (char === '"' || char === "'" || char === "`") quote = char;
      else if (char === "{") depth++;
      else if (char === "}" && --depth === 0) {
        blocks.push(source.slice(brace + 1, index));
        break;
      }
    }
  }
  return blocks;
}

test("all UI output payload declarations are concrete", () => {
  const root = join(import.meta.dir, "../components");
  const offenders: string[] = [];
  for (const file of readdirSync(root).filter((name) => name.endsWith(".wrn"))) {
    for (const block of outputBlocks(readFileSync(join(root, file), "utf8"))) {
      if (/\bunknown\b/.test(block)) offenders.push(file);
    }
  }
  expect(offenders).toEqual([]);
});
