/**
 * pipeline/release-classification.ts
 *
 * Classifies documents in a content release for evaluation tier assignment.
 *
 * Phase 4a of the Scenario Matrix implementation.
 *
 * Given a ReleaseImpact (added/modified/removed/unchanged) and the task
 * mappings, this module classifies each document as:
 *
 * - **Tier A**: New document in an area that has existing evaluation tasks.
 *   The document can be injected into existing task contexts and evaluated.
 * - **Tier B**: New document in an area with no evaluation tasks.
 *   Only a directional probe is possible (no scored evaluation).
 * - **not-applicable**: Updated, removed, or unchanged documents (these
 *   follow the standard before/after comparison flow from Phase 2).
 *
 * @see docs/archive/exec-plans/scenario-matrix-implementation/phase-4-content-release-integration.md
 */
// ---------------------------------------------------------------------------
// Public API
// ---------------------------------------------------------------------------
/**
 * Classify all documents in a content release for evaluation.
 *
 * @param releaseImpact - Added/modified/removed/unchanged slugs from the release
 * @param reverseMapping - Slug → affected area/task mapping
 * @param featureAreas - Set of area names that have task files
 * @param features - Product feature registry (optional, for section-based area inference)
 * @returns Release classification with per-document tier assignment
 */
export function classifyRelease(releaseImpact, reverseMapping, featureAreas, features) {
    const documents = [];
    // Build a section → area lookup from features registry
    const sectionToAreas = buildSectionMapping(features);
    // Classify added documents (new in the release)
    for (const slug of releaseImpact.added) {
        const doc = classifyDocument(slug, "new", reverseMapping, featureAreas, sectionToAreas);
        documents.push(doc);
    }
    // Classify modified documents (updated in the release)
    for (const slug of releaseImpact.modified) {
        const doc = classifyDocument(slug, "updated", reverseMapping, featureAreas, sectionToAreas);
        documents.push(doc);
    }
    // Classify removed documents
    for (const slug of releaseImpact.removed) {
        const doc = classifyDocument(slug, "removed", reverseMapping, featureAreas, sectionToAreas);
        documents.push(doc);
    }
    // Compute summary
    const tierA = documents.filter((d) => d.tier === "A").length;
    const tierB = documents.filter((d) => d.tier === "B").length;
    const tracked = documents.filter((d) => d.tracked).length;
    const updated = documents.filter((d) => d.changeType === "updated").length;
    const untracked = documents.filter((d) => !d.tracked).length;
    return {
        documents,
        generatedAt: new Date().toISOString(),
        summary: {
            tierA,
            tierB,
            total: documents.length,
            tracked,
            untracked,
            updated,
        },
    };
}
/**
 * Format a release classification for console output.
 */
export function formatReleaseClassificationConsole(classification) {
    const lines = [];
    const { summary } = classification;
    lines.push("📦 RELEASE DOCUMENT CLASSIFICATION");
    lines.push("");
    lines.push(`  ${summary.total} documents: ${summary.tracked} tracked, ${summary.untracked} untracked`);
    if (summary.tierA > 0 || summary.tierB > 0) {
        lines.push(`  New documents: ${summary.tierA} Tier A (evaluable), ${summary.tierB} Tier B (probe only)`);
    }
    lines.push("");
    // Group by change type
    const byType = groupByChangeType(classification.documents);
    if (byType.new.length > 0) {
        lines.push("  NEW DOCUMENTS:");
        for (const doc of byType.new) {
            const tierLabel = doc.tier === "A" ? "Tier A" : "Tier B";
            const areas = doc.affectedAreas.length > 0
                ? doc.affectedAreas.join(", ")
                : "(no matching area)";
            lines.push(`    ${tierIcon(doc.tier)} ${doc.slug} → ${tierLabel} [${areas}]`);
        }
        lines.push("");
    }
    if (byType.updated.length > 0) {
        lines.push("  UPDATED DOCUMENTS:");
        for (const doc of byType.updated) {
            const tracked = doc.tracked ? "tracked" : "untracked";
            const areas = doc.affectedAreas.length > 0
                ? doc.affectedAreas.join(", ")
                : "(no tasks)";
            lines.push(`    📝 ${doc.slug} → ${tracked} [${areas}]`);
        }
        lines.push("");
    }
    if (byType.removed.length > 0) {
        lines.push("  REMOVED DOCUMENTS:");
        for (const doc of byType.removed) {
            lines.push(`    🗑️  ${doc.slug}`);
        }
        lines.push("");
    }
    return lines.join("\n");
}
/**
 * Format a release classification as markdown for PR comments.
 */
export function formatReleaseClassificationMarkdown(classification) {
    const lines = [];
    const { summary } = classification;
    lines.push("### 📦 Release Document Classification");
    lines.push("");
    lines.push(`**${summary.total} documents**: ${summary.tracked} tracked, ${summary.untracked} untracked`);
    lines.push("");
    if (classification.documents.length > 0) {
        lines.push("| Document | Change | Tier | Areas |");
        lines.push("|----------|--------|------|-------|");
        for (const doc of classification.documents) {
            const tierLabel = doc.tier === "A" ? "🟢 A" : doc.tier === "B" ? "🟡 B" : "—";
            const areas = doc.affectedAreas.length > 0 ? doc.affectedAreas.join(", ") : "—";
            lines.push(`| \`${doc.slug}\` | ${doc.changeType} | ${tierLabel} | ${areas} |`);
        }
        lines.push("");
    }
    return lines.join("\n");
}
// ---------------------------------------------------------------------------
// Formatting
// ---------------------------------------------------------------------------
/**
 * Extract Tier A documents — new documents that can be injected into
 * existing task contexts for evaluation.
 */
export function getTierADocuments(classification) {
    return classification.documents.filter((d) => d.tier === "A");
}
/**
 * Extract Tier B documents — new documents in areas without tasks,
 * suitable for directional probes only.
 */
export function getTierBDocuments(classification) {
    return classification.documents.filter((d) => d.tier === "B");
}
// ---------------------------------------------------------------------------
// Internal helpers
// ---------------------------------------------------------------------------
/** Build a section → area names lookup from the feature registry */
function buildSectionMapping(features) {
    const mapping = new Map();
    if (!features)
        return mapping;
    for (const feature of features) {
        if (feature.status !== "covered" || !feature.area)
            continue;
        for (const section of feature.sections) {
            const existing = mapping.get(section) ?? [];
            if (!existing.includes(feature.area)) {
                existing.push(feature.area);
            }
            mapping.set(section, existing);
        }
    }
    return mapping;
}
/** Classify a single document */
function classifyDocument(slug, changeType, reverseMapping, featureAreas, _sectionToAreas) {
    const targets = reverseMapping.get(slug) ?? [];
    const affectedAreas = [...new Set(targets.map((t) => t.area))].sort();
    const tracked = targets.length > 0;
    // Determine tier for new documents
    let tier = "not-applicable";
    if (changeType === "new") {
        if (affectedAreas.length > 0) {
            // New doc matches existing tasks → Tier A
            tier = "A";
        }
        else {
            // Check if any feature area exists for this document
            // Try to infer area from slug prefix
            const inferredArea = inferAreaFromSlug(slug, featureAreas);
            if (inferredArea) {
                tier = "A";
                affectedAreas.push(inferredArea);
            }
            else {
                tier = "B";
            }
        }
    }
    return {
        affectedAreas,
        changeType,
        slug,
        tier,
        tracked,
    };
}
/** Group documents by change type */
function groupByChangeType(docs) {
    return {
        new: docs.filter((d) => d.changeType === "new"),
        removed: docs.filter((d) => d.changeType === "removed"),
        updated: docs.filter((d) => d.changeType === "updated"),
    };
}
/** Try to infer a feature area from a document slug prefix */
function inferAreaFromSlug(slug, featureAreas) {
    // Try progressively shorter prefixes of the slug
    const parts = slug.split("-");
    for (let i = parts.length; i >= 1; i--) {
        const candidate = parts.slice(0, i).join("-");
        if (featureAreas.has(candidate))
            return candidate;
    }
    return undefined;
}
/** Get icon for a tier */
function tierIcon(tier) {
    switch (tier) {
        case "A":
            return "🟢";
        case "B":
            return "🟡";
        case "not-applicable":
            return "⚪";
    }
}
