import { existsSync, mkdirSync, readdirSync, readFileSync } from "node:fs";
import { join } from "node:path";
export const ADR_DIR = "docs/adr";
export function getAdrDir(projectRoot) {
    return join(projectRoot, ADR_DIR);
}
export function createAdrSlug(title) {
    return title
        .toLowerCase()
        .replace(/[^a-z0-9]+/g, "-")
        .replace(/^-|-$/g, "")
        .slice(0, 80);
}
export function createAdrFileName(id, title) {
    return `${String(id).padStart(4, "0")}-${createAdrSlug(title) || "decision"}.md`;
}
export function createAdrMarkdown(record) {
    const supersedes = record.supersedes && record.supersedes.length > 0 ? record.supersedes.join(", ") : "none";
    const supersededBy = record.supersededBy ?? "none";
    const links = record.links && record.links.length > 0 ? record.links.map((link) => `- ${link}`).join("\n") : "- none";
    return `# ${record.id}: ${record.title}

Status: ${record.status}
Date: ${record.date}
Supersedes: ${supersedes}
Superseded by: ${supersededBy}

## Context

${record.context.trim()}

## Decision

${record.decision.trim()}

## Consequences

${record.consequences.trim()}

## Links

${links}
`;
}
function readField(markdown, field) {
    return markdown.match(new RegExp(`^${field}:\\s*(.+)$`, "m"))?.[1]?.trim();
}
function readSection(markdown, heading) {
    const start = markdown.indexOf(`## ${heading}`);
    if (start === -1)
        return "";
    const bodyStart = start + `## ${heading}`.length;
    const next = markdown.indexOf("\n## ", bodyStart);
    return markdown.slice(bodyStart, next === -1 ? markdown.length : next).trim();
}
function parseListField(value) {
    if (!value || value === "none")
        return undefined;
    return value
        .split(",")
        .map((entry) => entry.trim())
        .filter(Boolean);
}
export function parseAdrMarkdown(markdown, path) {
    const titleMatch = markdown.match(/^#\s+([^:]+):\s+(.+)$/m);
    if (!titleMatch)
        return undefined;
    const status = readField(markdown, "Status");
    if (!status || !["proposed", "accepted", "superseded", "rejected"].includes(status))
        return undefined;
    return {
        id: titleMatch[1].trim(),
        title: titleMatch[2].trim(),
        status,
        date: readField(markdown, "Date") ?? "unknown",
        context: readSection(markdown, "Context"),
        decision: readSection(markdown, "Decision"),
        consequences: readSection(markdown, "Consequences"),
        supersedes: parseListField(readField(markdown, "Supersedes")),
        supersededBy: readField(markdown, "Superseded by")?.replace(/^none$/, "") || undefined,
        links: readSection(markdown, "Links")
            .split(/\r?\n/)
            .map((line) => line.replace(/^-\s*/, "").trim())
            .filter((line) => line && line !== "none"),
        path,
    };
}
export function readAdrIndex(projectRoot) {
    const dir = getAdrDir(projectRoot);
    if (!existsSync(dir))
        return { active: [], superseded: [], proposed: [], rejected: [] };
    const records = readdirSync(dir)
        .filter((entry) => entry.endsWith(".md"))
        .flatMap((entry) => {
        const path = join(dir, entry);
        const record = parseAdrMarkdown(readFileSync(path, "utf-8"), path);
        return record ? [record] : [];
    });
    return {
        active: records.filter((record) => record.status === "accepted" && !record.supersededBy),
        superseded: records.filter((record) => record.status === "superseded" || Boolean(record.supersededBy)),
        proposed: records.filter((record) => record.status === "proposed"),
        rejected: records.filter((record) => record.status === "rejected"),
    };
}
function adrScore(record, queryTokens) {
    const haystack = `${record.title} ${record.context} ${record.decision} ${record.consequences}`.toLowerCase();
    return queryTokens.filter((token) => haystack.includes(token)).length;
}
export function findRelevantAdrs(records, query, limit = 4) {
    const tokens = query
        .toLowerCase()
        .split(/[^a-z0-9_-]+/i)
        .map((token) => token.trim())
        .filter((token) => token.length >= 3);
    if (tokens.length === 0)
        return [];
    return records
        .map((record) => ({ record, score: adrScore(record, tokens) }))
        .filter((entry) => entry.score > 0)
        .sort((left, right) => right.score - left.score)
        .slice(0, limit)
        .map((entry) => entry.record);
}
export function renderAdrCapsule(records) {
    if (records.length === 0)
        return undefined;
    return [
        "Relevant ADRs:",
        ...records.map((record) => `- ${record.id} [${record.status}] ${record.title}: ${record.decision}`),
    ].join("\n");
}
export function ensureAdrDir(projectRoot) {
    const dir = getAdrDir(projectRoot);
    mkdirSync(dir, { recursive: true });
    return dir;
}
//# sourceMappingURL=adr-format.js.map