"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.architectureReviewReportJsonPathRelative = exports.architectureReviewReportMarkdownPathRelative = void 0;
exports.buildArchitectureReviewReportPayload = buildArchitectureReviewReportPayload;
exports.renderArchitectureReviewReportJson = renderArchitectureReviewReportJson;
exports.buildReviewGeneratePrerequisiteMessage = buildReviewGeneratePrerequisiteMessage;
exports.renderArchitectureReviewReportMarkdown = renderArchitectureReviewReportMarkdown;
const validationRuleExplanations_1 = require("../validationRuleExplanations");
const resolveRuleAdrs_1 = require("../resolveRuleAdrs");
const architectureReviewReporter_1 = require("./architectureReviewReporter");
exports.architectureReviewReportMarkdownPathRelative = '.archpilot/reports/architecture-review-report.md';
exports.architectureReviewReportJsonPathRelative = '.archpilot/reports/architecture-review-report.json';
function getFindingLocation(finding) {
    if (!finding.sourceFile) {
        return undefined;
    }
    if (finding.sourceLine === undefined) {
        return finding.sourceFile;
    }
    return `${finding.sourceFile}:${finding.sourceLine}`;
}
function toRenderedFinding(finding, discoveredAdrs) {
    const explanation = (0, validationRuleExplanations_1.resolveValidationExplanation)(finding.id);
    return {
        ruleId: finding.id,
        title: finding.title,
        severity: finding.severity,
        classification: finding.kind,
        message: finding.message,
        whyItMatters: explanation.whyItMatters,
        howToFix: explanation.howToFix,
        relatedAdrs: (0, resolveRuleAdrs_1.resolveRuleAdrs)(finding.id, discoveredAdrs),
        ...(finding.module ? { module: finding.module } : {}),
        ...(finding.target ? { target: finding.target } : {}),
        ...(finding.filePath ? { filePath: finding.filePath } : {}),
        ...(finding.table ? { table: finding.table } : {}),
        ...(finding.api ? { api: finding.api } : {}),
        ...(finding.findingType ? { findingType: finding.findingType } : {}),
        ...(getFindingLocation(finding) ? { location: getFindingLocation(finding) } : {}),
    };
}
function toLines(values) {
    return values.length > 0 ? values.map((value) => `- ${value}`).join('\n') : '- (none)';
}
function buildPostureLabel(healthTrend) {
    if (!healthTrend) {
        return 'Not available in this run';
    }
    if (healthTrend.trendDirection === 'improving') {
        return 'Improving';
    }
    if (healthTrend.trendDirection === 'declining') {
        return 'Declining';
    }
    if (healthTrend.trendDirection === 'stable') {
        return 'Stable';
    }
    return 'Not available in this run';
}
function buildHighlights(summary) {
    const blocking = summary.findings
        .filter((finding) => finding.severity === 'error')
        .slice(0, 3)
        .map((finding) => `[${finding.id}] ${finding.title}`);
    const advisory = summary.findings
        .filter((finding) => finding.severity === 'warning')
        .slice(0, 3)
        .map((finding) => `[${finding.id}] ${finding.title}`);
    const positives = [];
    if (summary.counts.errors === 0 && summary.counts.warnings === 0) {
        positives.push('No active error/warning architecture violations.');
    }
    if (summary.counts.exceptions && summary.counts.exceptions > 0) {
        positives.push(`${summary.counts.exceptions} approved exception(s) were applied deterministically.`);
    }
    return { blocking, advisory, positives };
}
function buildImpactAvailability(summary) {
    const hasAnyScopedSignals = summary.impactAnalysis.changedModules.length > 0 ||
        summary.impactAnalysis.directDependents.length > 0 ||
        summary.impactAnalysis.transitiveDependents.length > 0 ||
        (summary.impactAnalysis.affectedSurface?.impactedContracts.length ?? 0) > 0 ||
        (summary.impactAnalysis.affectedSurface?.impactedPublicEntrypoints.length ?? 0) > 0 ||
        (summary.impactAnalysis.affectedSurface?.impactedAdrs.length ?? 0) > 0 ||
        (summary.impactAnalysis.affectedSurface?.impactedArchitectureArtifacts.length ?? 0) > 0;
    if (hasAnyScopedSignals) {
        return { available: true };
    }
    if (!summary.changeRisk.signals.diffContextAvailable) {
        return {
            available: false,
            note: 'Change-scoped impact data is not available for this full validation run.',
        };
    }
    return { available: false, note: 'No architecture impact signals were detected for this run.' };
}
function buildNextActions(summary) {
    const actions = [];
    const topBlocking = summary.findings.find((finding) => finding.severity === 'error');
    if (topBlocking) {
        actions.push(`Resolve ${topBlocking.id} first to reduce blocking architecture risk.`);
    }
    if (summary.setupGaps > 0) {
        actions.push('Address setup gaps first (for example `archpilot bootstrap --with-contracts`) before deeper governance review.');
    }
    if (summary.adrRequirement.required) {
        actions.push(summary.adrRequirement.suggestedCommand
            ? `Document the change with ADR coverage: ${summary.adrRequirement.suggestedCommand}`
            : 'Document the change with ADR coverage for the triggered policy outcome.');
    }
    if ((summary.safetyControls?.findings.length ?? 0) > 0) {
        for (const finding of summary.safetyControls?.findings ?? []) {
            if (finding.ruleId === 'AP-SAFE-002') {
                actions.push('Create rollback evidence: .archpilot/rollout/rollback-plan.md.');
            }
            if (finding.ruleId === 'AP-SAFE-003') {
                actions.push('Create or fix feature flag rollout evidence: .archpilot/rollout/feature-flags.json.');
            }
        }
    }
    if (summary.findings.length > 0) {
        const topFixRule = summary.findings[0]?.id;
        if (topFixRule) {
            actions.push(`Review available deterministic fix actions: \`archpilot fix ${topFixRule}\`.`);
        }
    }
    if (actions.length === 0) {
        actions.push('No immediate architecture remediation actions are required.');
    }
    return actions.slice(0, 4);
}
function buildArchitectureReviewReportPayload(input) {
    const summary = input.summary;
    const discoveredAdrs = input.discoveredAdrs ?? [];
    const highlights = buildHighlights(summary);
    const impactAvailability = buildImpactAvailability(summary);
    const blockingFindings = summary.findings.filter((finding) => finding.severity === 'error');
    const warningFindings = summary.findings.filter((finding) => finding.severity === 'warning');
    const setupGapFindings = summary.findings.filter((finding) => finding.kind === 'setup-gap');
    const exceptionFindings = summary.passedChecks.filter((finding) => finding.status === 'exception');
    const nextActions = buildNextActions(summary);
    const postureTrend = buildPostureLabel(input.healthTrend);
    return {
        generatedAt: summary.generatedAtUtc,
        project: {
            projectName: summary.projectName,
            ...(input.projectIdentity ? input.projectIdentity : {}),
        },
        summary: {
            outcome: summary.enforcement.enforcementDecision ?? summary.enforcement.action.toUpperCase(),
            postureTrend,
            totalFindings: summary.findings.length,
            counts: summary.counts,
        },
        scores: {
            architectureHealth: summary.healthScore,
            setupReadiness: summary.readinessScore,
            categoryScores: summary.categoryScores,
            readinessCategoryScores: summary.readinessCategoryScores,
            scoreExplanation: summary.scoreExplanation,
        },
        risk: {
            governanceRiskLevel: summary.risk.level.toUpperCase(),
            changeRiskLevel: summary.changeRisk.riskLevel.toUpperCase(),
            changeRiskSummary: summary.changeRisk.summary,
            reasons: summary.risk.reasons,
        },
        enforcement: {
            policyLevel: summary.enforcement.policyLevel ?? 'n/a',
            enforcementDecision: summary.enforcement.enforcementDecision ?? summary.enforcement.action.toUpperCase(),
            matchedThreshold: summary.enforcement.matchedThreshold,
            reasons: summary.enforcement.reasons,
            ciExitBehavior: summary.enforcement.ciExitBehavior,
        },
        adr: {
            required: summary.adrRequirement.required,
            satisfied: summary.adrRequirement.required ? summary.adrRequirement.satisfied : 'n/a',
            reasons: summary.adrRequirement.reasons,
            suggestedCommand: summary.adrRequirement.suggestedCommand,
            suggestedFilenameHint: summary.adrRequirement.suggestedFilenameHint,
        },
        safetyControls: summary.safetyControls
            ? {
                triggered: summary.safetyControls.triggered,
                applicable: summary.safetyControls.applicable,
                triggerReasons: summary.safetyControls.triggerReasons,
                summary: summary.safetyControls.summary,
                missingControls: summary.safetyControls.missingControls,
                findings: summary.safetyControls.findings,
                controlsChecked: summary.safetyControls.controlsChecked,
            }
            : {
                triggered: false,
                applicable: false,
                triggerReasons: [],
                summary: 'Safety controls analysis not available in this run.',
                missingControls: [],
                findings: [],
                controlsChecked: [],
            },
        exceptions: {
            count: summary.counts.exceptions ?? 0,
            findings: exceptionFindings.map((finding) => toRenderedFinding(finding, discoveredAdrs)),
        },
        suppressions: {
            count: summary.counts.suppressed,
            ignoredCount: summary.counts.ignoredSuppressions,
        },
        impact: {
            available: impactAvailability.available,
            ...(impactAvailability.note ? { note: impactAvailability.note } : {}),
            level: summary.impactAnalysis.impactLevel,
            score: summary.impactAnalysis.impactRadiusScore,
            changedModules: summary.impactAnalysis.changedModules,
            directlyAffectedModules: summary.impactAnalysis.affectedSurface?.directlyAffectedModules ?? [],
            transitivelyAffectedModules: summary.impactAnalysis.affectedSurface?.transitivelyAffectedModules ?? [],
            impactedContracts: summary.impactAnalysis.affectedSurface?.impactedContracts ?? [],
            impactedPublicEntrypoints: summary.impactAnalysis.affectedSurface?.impactedPublicEntrypoints ?? [],
            impactedAdrs: summary.impactAnalysis.affectedSurface?.impactedAdrs ?? [],
            impactedArchitectureArtifacts: summary.impactAnalysis.affectedSurface?.impactedArchitectureArtifacts ?? [],
        },
        highlights,
        findings: {
            blocking: blockingFindings.map((finding) => toRenderedFinding(finding, discoveredAdrs)),
            warnings: warningFindings.map((finding) => toRenderedFinding(finding, discoveredAdrs)),
            setupGaps: setupGapFindings.map((finding) => toRenderedFinding(finding, discoveredAdrs)),
            exceptions: exceptionFindings.map((finding) => toRenderedFinding(finding, discoveredAdrs)),
        },
        ...(summary.componentSummary ? { componentSummary: summary.componentSummary } : {}),
        nextActions,
    };
}
function renderArchitectureReviewReportJson(input) {
    return `${JSON.stringify(buildArchitectureReviewReportPayload(input), null, 2)}\n`;
}
function buildReviewGeneratePrerequisiteMessage() {
    return 'Architecture review summary artifact is missing. Run `archpilot validate` first to generate .archpilot/reports/architecture-summary.json.';
}
function renderArchitectureReviewReportMarkdown(input) {
    const payload = buildArchitectureReviewReportPayload(input);
    const summary = input.summary;
    const highlights = payload.highlights;
    const findings = payload.findings;
    const impact = payload.impact;
    const nextActions = payload.nextActions;
    const safetyControls = payload.safetyControls;
    const adrDisplay = (0, architectureReviewReporter_1.resolveAdrRequirementDisplay)({
        enforcementAction: summary.enforcement.action,
        adrRequirement: summary.adrRequirement,
        findings: summary.findings,
    });
    const renderFindingGroup = (items) => items.length === 0
        ? '- (none)'
        : items
            .map((item) => [
            `- [${item.ruleId}] ${item.title}`,
            `  - Severity: ${item.severity}`,
            `  - Classification: ${item.classification}`,
            `  - Message: ${item.message}`,
            ...(item.module ? [`  - Module: ${item.module}`] : []),
            ...(item.target ? [`  - Target: ${item.target}`] : []),
            ...(item.filePath ? [`  - File Path: ${item.filePath}`] : []),
            ...(item.api ? [`  - API: ${item.api}`] : []),
            ...(item.table ? [`  - Table: ${item.table}`] : []),
            ...(item.findingType ? [`  - Type: ${item.findingType}`] : []),
            ...(item.location ? [`  - Location: ${item.location}`] : []),
            `  - Why it matters: ${item.whyItMatters}`,
            `  - How to fix: ${item.howToFix}`,
            `  - Related ADRs: ${item.relatedAdrs.length > 0
                ? item.relatedAdrs
                    .map((adr) => `${adr.id}${adr.filePath ? ` (${adr.filePath})` : ''}`)
                    .join(', ')
                : '(none)'}`,
        ].join('\n'))
            .join('\n');
    return `# ArchPilot Architecture Review Report

## Executive Summary
- Review outcome: ${String(payload.summary.outcome)}
- Architecture Health Score: ${summary.healthScore} / 100
- Setup Readiness Score: ${summary.readinessScore} / 100
- Trend: ${String(payload.summary.postureTrend)}
- Change Risk: ${summary.changeRisk.riskLevel.toUpperCase()} (${summary.changeRisk.summary})
- Architecture Review Level: ${summary.risk.level.toUpperCase()}
- Enforcement Outcome: ${summary.enforcement.enforcementDecision ?? summary.enforcement.action.toUpperCase()}
- ADR Required: ${adrDisplay.requiredLabel}
- ADR Satisfied: ${adrDisplay.satisfiedLabel}
- Approved Exceptions: ${summary.counts.exceptions ?? 0}
- Timestamp (UTC): ${summary.generatedAtUtc}
- Project: ${summary.projectName}
${input.projectIdentity ? `- Repository ID: ${input.projectIdentity.repositoryId}` : ''}

## Review Highlights
### Top Blocking Concerns
${toLines(highlights.blocking)}
### Top Advisory Concerns
${toLines(highlights.advisory)}
### Notable Positives
${toLines(highlights.positives)}

## Architecture Posture
- Findings: errors=${summary.counts.errors}, warnings=${summary.counts.warnings}, info=${summary.counts.info}
- Classification: violations=${summary.qualityFindings}, setup-gaps=${summary.setupGaps}, guidance=${summary.guidanceFindings}, exceptions=${summary.counts.exceptions ?? 0}
- Score breakdown: architecture=${summary.healthScore}/100, readiness=${summary.readinessScore}/100
- Weighted base health: ${summary.scoreExplanation.weightedBaseScore}/100
- Posture trend: ${String(payload.summary.postureTrend)}

### Largest Score Contributors
${summary.scoreExplanation.largestScoreContributors.length === 0
        ? '- (none)'
        : summary.scoreExplanation.largestScoreContributors.map((entry) => `- ${entry}`).join('\n')}

## Change Impact Summary
${impact.available
        ? `- Changed modules: ${impact.changedModules.join(', ') || '(none)'}
- Directly affected modules: ${impact.directlyAffectedModules.join(', ') || '(none)'}
- Transitively affected modules: ${impact.transitivelyAffectedModules.join(', ') || '(none)'}
- Impacted contracts: ${impact.impactedContracts.join(', ') || '(none)'}
- Impacted public entrypoints: ${impact.impactedPublicEntrypoints.join(', ') || '(none)'}
- Impacted ADRs: ${impact.impactedAdrs.join(', ') || '(none)'}
- Impacted architecture artifacts: ${impact.impactedArchitectureArtifacts.join(', ') || '(none)'}`
        : `- ${impact.note ?? 'Not available in this run.'}`}

## Enforcement and ADR Review
- Risk level: ${summary.risk.level.toUpperCase()}
- Policy level: ${summary.enforcement.policyLevel?.toUpperCase() ?? 'N/A'}
- Matched threshold: ${summary.enforcement.matchedThreshold
        ? `${summary.enforcement.matchedThreshold.id ?? '(unknown)'}`
        : 'N/A'}
- Enforcement decision: ${summary.enforcement.enforcementDecision ?? summary.enforcement.action.toUpperCase()}
- ADR Required: ${adrDisplay.requiredLabel}
- ADR Satisfied: ${adrDisplay.satisfiedLabel}
- Reasons:
${toLines(summary.enforcement.reasons)}
- ADR Reasons:
${toLines(adrDisplay.reasons)}
${adrDisplay.state === 'required' && summary.adrRequirement.suggestedCommand
        ? `- Suggested ADR command: ${summary.adrRequirement.suggestedCommand}`
        : ''}
${adrDisplay.state === 'required' && summary.adrRequirement.suggestedFilenameHint
        ? `- Suggested ADR filename hint: ${summary.adrRequirement.suggestedFilenameHint}`
        : ''}

## Recommended Deployment Safety Controls
- Triggered: ${safetyControls.triggered ? 'YES' : 'NO'}
- Applicable: ${safetyControls.applicable ? 'YES' : 'NO'}
- Summary: ${safetyControls.summary}
- Trigger reasons:
${toLines(safetyControls.triggerReasons)}
- Controls checked:
${safetyControls.controlsChecked.length === 0
        ? '- (none)'
        : safetyControls.controlsChecked
            .map((control) => `- ${control.controlType}: ${control.status} (required=${control.required ? 'yes' : 'no'})${control.evidencePath ? ` [${control.evidencePath}]` : ''}${control.evidenceDetail ? ` (${control.evidenceDetail})` : ''}`)
            .join('\n')}
- Missing controls:
${safetyControls.findings.length === 0
        ? '- (none)'
        : safetyControls.findings
            .map((finding) => `- [${finding.ruleId}] ${finding.message}${finding.evidencePath ? ` (${finding.evidencePath})` : ''}`)
            .join('\n')}

## Exceptions and Suppressions
- Approved exceptions matched: ${summary.counts.exceptions ?? 0}
- Suppressed findings: ${summary.counts.suppressed}
- Ignored suppression directives: ${summary.counts.ignoredSuppressions}

## Key Findings
### 1. Blocking / Highest Severity Violations
${renderFindingGroup(findings.blocking)}
### 2. Warnings / Advisory Issues
${renderFindingGroup(findings.warnings)}
### 3. Setup Gaps
${renderFindingGroup(findings.setupGaps)}
### 4. Exceptions (Summary)
${renderFindingGroup(findings.exceptions)}

## Recommended Next Actions
${toLines(nextActions)}
`;
}
//# sourceMappingURL=architectureReviewReportGenerator.js.map