const CHARS_PER_TOKEN = 4;
/** Converts a community name to a URL-safe kebab-case slug. */
export function toSlug(name) {
    return name
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, "-")
        .replace(/^-|-$/g, "");
}
export function buildUniqueSlugs(communities, options) {
    const nameToSlug = new Map();
    const seen = new Map();
    const useWorkspace = options?.monorepo === true && (options.workspaces?.length ?? 0) > 0;
    const workspaces = options?.workspaces ?? [];
    for (const c of communities) {
        let base = toSlug(c.name) || "community";
        if (useWorkspace && c.files && c.files.length > 0) {
            const ws = workspaces.find((w) => c.files.some((f) => f.startsWith(w + "/") || f === w));
            if (ws)
                base = `${toSlug(ws)}-${base}`;
        }
        const count = seen.get(base) ?? 0;
        const slug = count === 0 ? base : `${base}-${count + 1}`;
        seen.set(base, count + 1);
        nameToSlug.set(c.name, slug);
    }
    return nameToSlug;
}
/**
 * Maps every file from every community to the community's kebab-case slug
 * using a collision-free slug map.
 */
export function buildFileToCommunityMap(communities, slugMap = buildUniqueSlugs(communities)) {
    const map = {};
    for (const c of communities) {
        const slug = slugMap.get(c.name) ?? toSlug(c.name);
        for (const f of c.files) {
            map[f] = slug;
        }
    }
    return map;
}
/**
 * Builds the wiki manifest — a single JSON artifact that describes every
 * generated wiki page and its metadata.
 */
export function buildWikiManifest(options) {
    const { index_hash, git_commit, pages, communities, oldManifest, degradedReasons, journalPages } = options;
    // File → community map
    const file_to_community = buildFileToCommunityMap(communities);
    // Token estimates: rough chars / 4 rounded up
    const token_estimates = {};
    for (const p of pages) {
        token_estimates[p.slug] = Math.ceil(p.content.length / CHARS_PER_TOKEN);
    }
    // Slug redirects: preserve whatever was in the old manifest
    const slug_redirects = {
        ...(oldManifest?.slug_redirects ?? {}),
    };
    // Extract [[slug]] outbound links from each page's content
    const linkRegex = /\[\[([^\]]+)\]\]/g;
    const builtPages = pages.map((p) => {
        const outbound_links = [];
        linkRegex.lastIndex = 0;
        let match;
        while ((match = linkRegex.exec(p.content)) !== null) {
            const target = match[1];
            if (target !== undefined) {
                outbound_links.push(target);
            }
        }
        return {
            slug: p.slug,
            title: p.title,
            type: p.type,
            file: p.file,
            outbound_links,
        };
    });
    // v2.1: concat journal pages verbatim (they are already well-formed entries)
    const allPages = journalPages !== undefined && journalPages.length > 0
        ? [...builtPages, ...journalPages]
        : builtPages;
    const degraded = (degradedReasons?.length ?? 0) > 0;
    return {
        manifest_schema_version: "2.1.0",
        generated_at: new Date().toISOString(),
        index_hash,
        git_commit,
        pages: allPages,
        slug_redirects,
        token_estimates,
        file_to_community,
        degraded,
        ...(degraded ? { degraded_reasons: degradedReasons } : {}),
    };
}
//# sourceMappingURL=wiki-manifest.js.map