// one-line descriptions for the home banner, taken from the docs' own index pages: the
// "what's here" list in README.md and each section README's list of its pages. nothing is
// written for the site, a page with no line in any index just shows its title.

import fs from "node:fs";
import path from "node:path";
import { toHtml } from "hast-util-to-html";
import type { Element } from "hast";
import { DOCS_DIR, type Doc } from "./docs";

const ITEM = /^\s*-\s*\[[^\]]*\]\(([^)#\s]+\.md)(?:#[^)]*)?\):\s*(.+)$/;

function inline(md: string): string {
  return md
    .replace(/[&<>]/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;" })[c]!)
    .replace(/`([^`]+)`/g, "<code>$1</code>")
    .replace(/\[([^\]]+)\]\([^)]*\)/g, "$1");
}

/** doc id -> blurb html, from every README's list items */
export function blurbs(docs: Map<string, Doc>): Map<string, string> {
  const out = new Map<string, string>();
  for (const id of docs.keys()) {
    if (id !== "README" && !id.endsWith("/README")) continue;
    const dir = path.posix.dirname(id);
    for (const line of fs.readFileSync(path.join(DOCS_DIR, `${id}.md`), "utf8").split("\n")) {
      const m = ITEM.exec(line);
      if (!m) continue;
      const target = path.posix.normalize(path.posix.join(dir === "." ? "" : dir, m[1].slice(0, -3)));
      if (!out.has(target)) out.set(target, inline(m[2].trim()));
    }
  }
  return out;
}

/** the first paragraph of a doc, for the section and home banners */
export function firstParagraph(doc: Doc): string | undefined {
  const p = doc.tree.children.find((n): n is Element => n.type === "element" && n.tagName === "p");
  return p && toHtml(p);
}
