// engine/dora-metrics/calculations.ts — DORA metric calculations (SPEC-033)
import { classifyMetric, classifyTier } from './benchmarks.js';
import { getCommitLog, getMergeCommitsToMain } from './git-log.js';
/**
 * Calculates deployment frequency (deploys per week) from commits to main branch.
 */
export function calculateDeploymentFrequency(commits, periodDays) {
    if (commits.length === 0 || periodDays === 0) {
        return 0;
    }
    const weeks = periodDays / 7;
    return Math.round((commits.length / weeks) * 100) / 100;
}
/**
 * Calculates lead time in hours from merge commits.
 * Note: Without PR data, this is an approximation.
 */
export function calculateLeadTime(mergeCommits) {
    if (mergeCommits.length < 2) {
        return 0;
    }
    const sorted = [...mergeCommits].sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
    let totalDiff = 0;
    let count = 0;
    for (let i = 1; i < sorted.length; i++) {
        const prev = sorted[i - 1];
        const curr = sorted[i];
        /* v8 ignore start */
        if (!prev || !curr) {
            continue;
        }
        /* v8 ignore stop */
        const diff = (new Date(curr.date).getTime() - new Date(prev.date).getTime()) / (1000 * 60 * 60);
        if (diff > 0 && diff < 24 * 30) {
            totalDiff += diff;
            count++;
        }
    }
    return count > 0 ? Math.round((totalDiff / count) * 100) / 100 : 0;
}
/**
 * Calculates Change Failure Rate: % of commits to main that are reverts.
 */
export function calculateChangeFailureRate(commits) {
    if (commits.length === 0) {
        return 0;
    }
    const revertCommits = commits.filter((c) => /^revert\b|^reverts?\b/i.test(c.subject));
    return Math.round((revertCommits.length / commits.length) * 100 * 100) / 100;
}
/**
 * Calculates MTTR (Mean Time to Restore) in hours.
 */
export function calculateMttr(commits) {
    const revertCommits = commits.filter((c) => /^revert\b|^reverts?\b/i.test(c.subject));
    if (revertCommits.length === 0) {
        return 0;
    }
    const sorted = [...commits].sort((a, b) => new Date(a.date).getTime() - new Date(b.date).getTime());
    let totalMttr = 0;
    let count = 0;
    for (const revert of revertCommits) {
        const revertDate = new Date(revert.date).getTime();
        const nextFix = sorted.find((c) => new Date(c.date).getTime() > revertDate && !/^revert\b/i.test(c.subject));
        if (nextFix) {
            const mttrHours = (new Date(nextFix.date).getTime() - revertDate) / (1000 * 60 * 60);
            if (mttrHours < 24 * 30) {
                totalMttr += mttrHours;
                count++;
            }
        }
    }
    return count > 0 ? Math.round((totalMttr / count) * 100) / 100 : 0;
}
/**
 * Calculates DORA metrics from local git history.
 */
export async function calculateDoraMetrics(projectPath, periodDays = 30) {
    const periodEnd = new Date().toISOString();
    const periodStart = new Date(Date.now() - periodDays * 24 * 60 * 60 * 1000).toISOString();
    const [allCommits, mainCommits] = await Promise.all([
        getCommitLog(projectPath, periodDays),
        getMergeCommitsToMain(projectPath, periodDays),
    ]);
    const deploymentFrequency = calculateDeploymentFrequency(mainCommits, periodDays);
    const leadTimeHours = calculateLeadTime(mainCommits);
    const changeFailureRate = calculateChangeFailureRate(mainCommits);
    const mttrHours = calculateMttr(mainCommits);
    const metrics = { deploymentFrequency, leadTimeHours, changeFailureRate, mttrHours };
    const tier = classifyTier(metrics);
    return {
        ...metrics,
        tier,
        periodStart,
        periodEnd,
        commitsAnalyzed: allCommits.length,
    };
}
export { classifyMetric, classifyTier };
//# sourceMappingURL=calculations.js.map