/**
 * Build a deterministic index of canonical site markdown pages.
 *
 * Walks `docs/site/pages/<locale>/*.md` (and nested subdirs), resolves
 * frontmatter from the markdown + optional sibling `.meta.json`, and
 * produces a flat index keyed by public route path.
 *
 * This mirrors `index_builder.ts` for `/docs` but with site-page semantics.
 *
 * Determinism: sort order is a pure function of (locale → nav_order → path).
 */
import fs from "node:fs";
import path from "node:path";
import { splitFrontmatter } from "./doc_frontmatter.js";
import { resolveSitePageFrontmatter, } from "./site_page_frontmatter.js";
import { shouldShowInternal } from "./visibility.js";
const SKIP_DIR_NAMES = new Set(["node_modules", ".git"]);
function compareStable(a, b) {
    return a < b ? -1 : a > b ? 1 : 0;
}
function collectSiteMarkdownFiles(root) {
    const out = [];
    const walk = (absDir, rel) => {
        if (!fs.existsSync(absDir))
            return;
        let entries;
        try {
            entries = fs.readdirSync(absDir, { withFileTypes: true });
        }
        catch {
            return;
        }
        for (const ent of entries) {
            if (ent.isDirectory()) {
                if (SKIP_DIR_NAMES.has(ent.name))
                    continue;
                walk(path.join(absDir, ent.name), rel ? `${rel}/${ent.name}` : ent.name);
            }
            else if (ent.isFile() && ent.name.endsWith(".md")) {
                out.push(rel ? `${rel}/${ent.name}` : ent.name);
            }
        }
    };
    walk(root, "");
    out.sort(compareStable);
    return out;
}
function loadMetaJson(mdAbsPath) {
    const base = mdAbsPath.replace(/\.md$/, ".meta.json");
    if (!fs.existsSync(base))
        return undefined;
    try {
        const raw = fs.readFileSync(base, "utf-8");
        return JSON.parse(raw);
    }
    catch {
        return undefined;
    }
}
function extractHeadings(body) {
    const headings = [];
    const lines = body.split(/\r?\n/);
    for (const line of lines) {
        const m = /^(#{1,6})\s+(.+?)\s*(?:\{#([^}]+)\})?\s*$/.exec(line);
        if (m) {
            const level = m[1].length;
            const text = m[2].replace(/\{#[^}]+\}\s*$/, "").trim();
            const explicitId = m[3];
            const id = explicitId ?? slugifyHeading(text);
            headings.push({ level, text, id });
        }
    }
    return headings;
}
function slugifyHeading(text) {
    return text
        .toLowerCase()
        .replace(/[^\w\s-]/g, "")
        .replace(/\s+/g, "-")
        .replace(/^-+|-+$/g, "");
}
export function buildSitePageIndex(opts) {
    const { sitePagesRoot, env } = opts;
    const files = collectSiteMarkdownFiles(sitePagesRoot);
    const pages = [];
    for (const rel of files) {
        const abs = path.join(sitePagesRoot, rel);
        let source;
        try {
            source = fs.readFileSync(abs, "utf-8");
        }
        catch {
            continue;
        }
        const metaJson = loadMetaJson(abs);
        const frontmatter = resolveSitePageFrontmatter(rel, source, metaJson);
        if (frontmatter.visibility === "internal" && !shouldShowInternal(env))
            continue;
        pages.push({
            path: frontmatter.path,
            locale: frontmatter.locale,
            frontmatter,
            repo_path: `docs/site/pages/${rel}`,
        });
    }
    pages.sort((a, b) => {
        if (a.locale !== b.locale)
            return compareStable(a.locale, b.locale);
        const aOrd = a.frontmatter.nav_order ?? 1000;
        const bOrd = b.frontmatter.nav_order ?? 1000;
        if (aOrd !== bOrd)
            return aOrd - bOrd;
        return compareStable(a.path, b.path);
    });
    return { pages, total: pages.length };
}
export function lookupSitePage(routePath, opts) {
    const { sitePagesRoot, env, locale = "en" } = opts;
    const normalizedPath = routePath.startsWith("/") ? routePath : `/${routePath}`;
    const files = collectSiteMarkdownFiles(sitePagesRoot);
    for (const rel of files) {
        const localePart = rel.split("/")[0];
        if (localePart !== locale)
            continue;
        const abs = path.join(sitePagesRoot, rel);
        let source;
        try {
            source = fs.readFileSync(abs, "utf-8");
        }
        catch {
            continue;
        }
        const metaJson = loadMetaJson(abs);
        const frontmatter = resolveSitePageFrontmatter(rel, source, metaJson);
        if (frontmatter.path !== normalizedPath)
            continue;
        if (frontmatter.visibility === "internal" && !shouldShowInternal(env))
            continue;
        const { body } = splitFrontmatter(source);
        const headings = extractHeadings(body);
        return {
            path: frontmatter.path,
            locale: frontmatter.locale,
            frontmatter,
            repo_path: `docs/site/pages/${rel}`,
            body,
            headings,
        };
    }
    return null;
}
//# sourceMappingURL=site_page_index_builder.js.map