import { readManifest } from './manifest-reader.js';
import { calculateHealthScore, classifyDepStatus } from './health-scorer.js';
import { scanForVulnerabilities } from './vulnerability-scanner.js';
// ---------------------------------------------------------------------------
// Severity mapping
// ---------------------------------------------------------------------------
function severityForStatus(code) {
    if (code === 'vulnerable') {
        return 'critical';
    }
    if (code === 'unmaintained' || code === 'outdated_major') {
        return 'warning';
    }
    return 'info';
}
// ---------------------------------------------------------------------------
// Delta computation
// ---------------------------------------------------------------------------
function computeDelta(current, last) {
    const lastMap = new Map(last.dependencies.map((d) => [d.name, d]));
    const currentMap = new Map(current.map((d) => [d.name, d]));
    const newVulnerabilities = current.filter((d) => d.statusCode === 'vulnerable' && lastMap.get(d.name)?.statusCode !== 'vulnerable');
    const resolved = [];
    for (const [name, lastDep] of lastMap) {
        const cur = currentMap.get(name);
        if (cur && lastDep.statusCode !== 'up_to_date' && cur.statusCode === 'up_to_date') {
            resolved.push(name);
        }
    }
    const STATUS_ORDER = [
        'up_to_date',
        'outdated_patch',
        'outdated_minor',
        'outdated_major',
        'unmaintained',
        'vulnerable',
    ];
    const worsened = current.filter((dep) => {
        const prev = lastMap.get(dep.name);
        if (!prev) {
            return false;
        }
        return STATUS_ORDER.indexOf(dep.statusCode) > STATUS_ORDER.indexOf(prev.statusCode);
    });
    return { newVulnerabilities, resolved, worsened };
}
// ---------------------------------------------------------------------------
// Main orchestrator
// ---------------------------------------------------------------------------
/**
 * Run a full stack audit for the given project path.
 */
export async function auditStack(projectPath, projectId, opts = {}) {
    const manifest = await readManifest(projectPath);
    // Build initial AuditedDependency list
    const rawDeps = Object.entries(manifest.directDependencies).map(([name, rangeStr]) => {
        const resolvedVersion = manifest.lockfileVersions.get(name) ?? rangeStr.replace(/^[^0-9]*/, '');
        const latestStableVersion = resolvedVersion; // no registry call — use resolved as "latest known"
        const statusCode = classifyDepStatus(resolvedVersion, latestStableVersion);
        const severity = severityForStatus(statusCode);
        return {
            name,
            currentVersion: resolvedVersion,
            latestStableVersion,
            statusCode,
            severity,
            cves: [],
            isTransitive: false,
        };
    });
    // Vulnerability scan
    const deps = scanForVulnerabilities(rawDeps, projectPath);
    // Health score
    const healthScore = calculateHealthScore(deps);
    const result = {
        projectId,
        timestamp: new Date().toISOString(),
        ecosystem: manifest.ecosystem,
        dependencies: deps,
        healthScore,
        runtimeVersions: manifest.runtimeVersions,
    };
    // Delta computation (when last audit available)
    if (opts.deltaMode && opts.lastAudit) {
        result.deltaFromLast = computeDelta(deps, opts.lastAudit);
    }
    return result;
}
//# sourceMappingURL=index.js.map