"use strict";
/**
 * Coverage artifact import.
 *
 * Detects and parses coverage reports produced by the project's test runner
 * so dxkit can report line-level truth instead of fabricating coverage from
 * filename matches.
 *
 * Supported formats per language pack (src/languages/*.ts):
 *   - typescript  → Istanbul summary + final
 *   - python      → coverage.py JSON
 *   - go          → coverprofile (coverage.out / cover.out)
 *   - rust        → lcov.info + cobertura XML (cargo llvm-cov)
 *   - csharp      → cobertura (dotnet test --collect:XPlat)
 *
 * `loadCoverage` is a thin wrapper over the capability dispatcher —
 * active language packs produce `CoverageResult` envelopes, the
 * descriptor's aggregator (last-wins in mixed-stack repos) reduces to
 * one, and we unwrap `.coverage` for callers. Returns null when no
 * artifact exists or parsing fails; callers (tests analyzer) should
 * treat a null return as "fall back to filename matching."
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadCoverage = loadCoverage;
exports.round1 = round1;
exports.toRelative = toRelative;
const languages_1 = require("../../languages");
const descriptors_1 = require("../../languages/capabilities/descriptors");
const dispatcher_1 = require("../dispatcher");
/**
 * Locate and parse a coverage artifact for the given repo root by
 * dispatching to every active language pack's coverage capability.
 * Returns null when no artifact is found or parsing fails.
 *
 * Mixed-stack repos: the COVERAGE descriptor's aggregator is
 * last-wins — if Node + Python both produce artifacts the later
 * provider wins. Cross-language coverage merging is out of scope for
 * now (would need per-language file weighting).
 */
async function loadCoverage(cwd) {
    const providers = [];
    for (const lang of (0, languages_1.detectActiveLanguages)(cwd)) {
        if (lang.capabilities?.coverage)
            providers.push(lang.capabilities.coverage);
    }
    if (providers.length === 0)
        return null;
    const envelope = await dispatcher_1.defaultDispatcher.gather(cwd, descriptors_1.COVERAGE, providers);
    return envelope?.coverage ?? null;
}
// ─── Helpers ────────────────────────────────────────────────────────────────
//
// Per-language parsers (Istanbul/coverage.py/Go cover-profile/lcov/cobertura)
// moved into their respective `src/languages/<id>.ts` packs in Phase
// 10i.0-LP.4. coverage.ts now hosts only the shared types + small
// utilities the parsers depend on. Adding a 6th language's coverage
// format is a pack-local change — no edits to this file required.
/** Round to one decimal place. Used by every coverage parser for the linePercent contract. */
function round1(n) {
    return Math.round(n * 10) / 10;
}
/** Turn an absolute or prefixed coverage path into a project-relative path. */
function toRelative(p, cwd) {
    let out = p.replace(/\\/g, '/');
    const cwdNorm = cwd.replace(/\\/g, '/');
    if (out.startsWith(cwdNorm + '/')) {
        out = out.slice(cwdNorm.length + 1);
    }
    else if (out === cwdNorm) {
        out = '';
    }
    if (out.startsWith('./'))
        out = out.slice(2);
    return out;
}
//# sourceMappingURL=coverage.js.map