// ---------------------------------------------------------------------------
// Impact classification
// ---------------------------------------------------------------------------
/** Determine impact level based on surface types and breakingIfRemoved flag. */
function classifyImpact(surface) {
    const hasBreaking = surface.surfaces.some((s) => s.isBreakingIfRemoved === true);
    if (hasBreaking) {
        return 'high';
    }
    const highImpactTypes = new Set(['rest-endpoint', 'database-schema', 'typescript-interface']);
    const hasHighType = surface.surfaces.some((s) => highImpactTypes.has(s.type));
    if (hasHighType) {
        return 'medium';
    }
    return 'low';
}
/** Check if a surface references terms from a change description. */
function surfaceMatchesChange(surface, changeDescription) {
    const descLower = changeDescription.toLowerCase();
    return surface.surfaces.some((s) => {
        const defLower = s.definition.toLowerCase();
        // Check if any word in definition appears in change description
        const words = defLower.split(/\s+/).filter((w) => w.length > 3);
        return words.some((w) => descLower.includes(w));
    });
}
// ---------------------------------------------------------------------------
// Analyze breaking changes
// ---------------------------------------------------------------------------
/**
 * Given a modified specId and a change description, find all other specs
 * that have registered surfaces potentially impacted by the change.
 */
export function analyzeBreakingChanges(sourceSpecId, changeDescription, allSurfaces) {
    const affectedSpecs = [];
    for (const surface of allSurfaces) {
        if (surface.specId === sourceSpecId) {
            continue;
        }
        // Check if this spec references surfaces related to the changed spec
        const isRelated = surfaceMatchesChange(surface, changeDescription);
        if (!isRelated) {
            continue;
        }
        const level = classifyImpact(surface);
        affectedSpecs.push({
            specId: surface.specId,
            reason: `References surfaces that overlap with: "${changeDescription.slice(0, 80)}"`,
            impactLevel: level,
        });
    }
    // Overall impact = highest individual impact
    let overallImpact = 'low';
    for (const a of affectedSpecs) {
        if (a.impactLevel === 'high') {
            overallImpact = 'high';
            break;
        }
        if (a.impactLevel === 'medium') {
            overallImpact = 'medium';
        }
    }
    return {
        sourceSpecId,
        changeDescription,
        affectedSpecs,
        overallImpact,
    };
}
// ---------------------------------------------------------------------------
// HTML report
// ---------------------------------------------------------------------------
/** Generate HTML report for dependency impact analysis. */
export function generateImpactReport(result) {
    const impactColor = {
        high: '#dc2626',
        medium: '#d97706',
        low: '#16a34a',
    };
    const badge = (level) => `<span style="background:${impactColor[level]};color:#fff;padding:2px 6px;border-radius:4px;font-size:12px">${level}</span>`;
    const rows = result.affectedSpecs
        .map((a) => `
    <tr>
      <td>${a.specId}</td>
      <td>${a.reason}</td>
      <td>${badge(a.impactLevel)}</td>
    </tr>`)
        .join('');
    return `<!DOCTYPE html>
<html>
<head><title>Dependency Impact Report</title>
<style>body{font-family:sans-serif;padding:20px}table{border-collapse:collapse;width:100%}
th,td{border:1px solid #ddd;padding:8px;text-align:left}th{background:#f3f4f6}</style>
</head>
<body>
<h1>Dependency Impact Report</h1>
<p>Source spec: <strong>${result.sourceSpecId}</strong></p>
<p>Change: <em>${result.changeDescription}</em></p>
<p>Overall impact: ${badge(result.overallImpact)}</p>
<h2>Affected Specs (${String(result.affectedSpecs.length)})</h2>
<table>
  <tr><th>Spec ID</th><th>Reason</th><th>Impact</th></tr>
  ${rows || '<tr><td colspan="3">No affected specs found.</td></tr>'}
</table>
</body>
</html>`;
}
// ---------------------------------------------------------------------------
// Compatibility check
// ---------------------------------------------------------------------------
/** Check which specs depend on a given spec's surfaces. */
export function checkApiCompatibility(specId, allSurfaces) {
    const own = allSurfaces.find((s) => s.specId === specId);
    if (!own) {
        return { dependents: [], surfaceCount: 0 };
    }
    const ownTerms = own.surfaces
        .flatMap((s) => s.definition.toLowerCase().split(/\s+/))
        .filter((w) => w.length > 3);
    const dependents = [];
    for (const surface of allSurfaces) {
        if (surface.specId === specId) {
            continue;
        }
        const otherText = surface.surfaces.map((s) => s.definition.toLowerCase()).join(' ');
        const overlaps = ownTerms.some((t) => otherText.includes(t));
        if (overlaps) {
            dependents.push(surface.specId);
        }
    }
    return { dependents, surfaceCount: own.surfaces.length };
}
//# sourceMappingURL=dependency-impact-analyzer.js.map