"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.analyzeDevActivity = analyzeDevActivity;
exports.formatDevReport = formatDevReport;
/**
 * Developer activity analyzer — public API.
 * Orthogonal to health (no dimension score).
 */
const path = __importStar(require("path"));
const cache_1 = require("../cache");
const health_1 = require("../health");
const report_date_1 = require("../tools/report-date");
const timing_1 = require("../tools/timing");
const gather_1 = require("./gather");
async function analyzeDevActivity(repoPath, since, options = {}) {
    const verbose = !!options.verbose;
    // Single canonical analysis envelope shared across consumers.
    // analyzeDevActivity reads stack + provenance from the cache so
    // its report header matches every other subcommand on the same
    // SHA. The git-log gathers (contributors / hot-files / velocity /
    // commit-quality) stay standalone — they're parameterized by the
    // since-date, which is orthogonal to the cache key, so they
    // legitimately run per-invocation.
    const cacheResult = await (0, cache_1.readOrBuildAnalysisResult)({
        cwd: repoPath,
        build: (cwd) => (0, health_1.gatherAnalysisResultBody)(cwd, { verbose }),
    });
    const { stack } = cacheResult;
    // Default: last 3 months
    const sinceDate = since || new Date(Date.now() - 90 * 24 * 60 * 60 * 1000).toISOString().slice(0, 10);
    const summary = (0, timing_1.timed)('summary', verbose, () => (0, gather_1.gatherSummary)(repoPath, sinceDate));
    const contributors = (0, timing_1.timed)('contributors', verbose, () => (0, gather_1.gatherContributors)(repoPath, sinceDate));
    const commitQuality = (0, timing_1.timed)('commit-quality', verbose, () => (0, gather_1.gatherCommitQuality)(repoPath, sinceDate));
    const hotFiles = (0, timing_1.timed)('hot-files', verbose, () => (0, gather_1.gatherHotFiles)(repoPath, sinceDate));
    const velocity = (0, timing_1.timed)('velocity', verbose, () => (0, gather_1.gatherVelocity)(repoPath, sinceDate));
    const nonMerge = summary.totalCommits - summary.mergeCommits;
    const mergeRatio = summary.totalCommits > 0
        ? Math.round((summary.mergeCommits / summary.totalCommits) * 1000) / 1000
        : 0;
    return {
        repo: stack.projectName || path.basename(cacheResult.cwd),
        analyzedAt: cacheResult.builtAt,
        commitSha: cacheResult.commitSha,
        branch: cacheResult.branch,
        period: { since: sinceDate, until: (0, report_date_1.getReportDate)() },
        summary: {
            totalCommits: summary.totalCommits,
            nonMergeCommits: nonMerge,
            mergeCommits: summary.mergeCommits,
            mergeRatio,
            contributors: contributors.length,
        },
        contributors,
        commitQuality,
        hotFiles,
        velocity,
        toolsUsed: ['git'],
    };
}
function formatDevReport(report, elapsed) {
    const L = [];
    L.push('# Developer Activity Report');
    L.push('');
    L.push(`**Date:** ${report.analyzedAt.slice(0, 10)}`);
    L.push(`**Period:** ${report.period.since} to ${report.period.until}`);
    L.push(`**Repository:** ${report.repo}`);
    L.push(`**Branch:** ${report.branch} (${report.commitSha})`);
    L.push('');
    L.push('---');
    L.push('');
    // Executive summary
    const s = report.summary;
    L.push('## Executive Summary');
    L.push('');
    L.push(`**${s.totalCommits} commits** (${s.nonMergeCommits} non-merge, ${s.mergeCommits} merge) ` +
        `from **${s.contributors} contributors**. ` +
        `Merge ratio: ${(s.mergeRatio * 100).toFixed(1)}%. ` +
        `Commit message quality: ${report.commitQuality.conventionalPercent}% conventional.`);
    L.push('');
    L.push('---');
    L.push('');
    // Contributors
    L.push('## 1. Developer Contributions');
    L.push('');
    L.push('| Rank | Developer | Commits | +Lines | -Lines | Net | Merges |');
    L.push('|------|-----------|---------|--------|--------|-----|--------|');
    report.contributors.forEach((c, i) => {
        const total = c.commits + c.mergeCommits;
        L.push(`| ${i + 1} | ${c.name} | ${total} | +${c.linesAdded.toLocaleString()} | -${c.linesRemoved.toLocaleString()} | ${c.netChange >= 0 ? '+' : ''}${c.netChange.toLocaleString()} | ${c.mergeCommits} |`);
    });
    L.push('');
    L.push('---');
    L.push('');
    // Commit quality
    const q = report.commitQuality;
    L.push('## 2. Commit Message Quality');
    L.push('');
    L.push('| Type | Count | % |');
    L.push('|------|-------|---|');
    L.push(`| Conventional (feat:, fix:, etc.) | ${q.conventional} | ${q.conventionalPercent}% |`);
    L.push(`| Descriptive | ${q.descriptive} | ${q.total > 0 ? ((q.descriptive / q.total) * 100).toFixed(1) : 0}% |`);
    L.push(`| Vague | ${q.vague} | ${q.total > 0 ? ((q.vague / q.total) * 100).toFixed(1) : 0}% |`);
    L.push('');
    if (q.conventionalPercent < 10) {
        L.push('> **Poor commit message quality.** Consider adopting [Conventional Commits](https://www.conventionalcommits.org/) for automated changelogs and clearer git history.');
    }
    L.push('');
    L.push('---');
    L.push('');
    // Hot files
    L.push('## 3. Hot Files (Most Changed)');
    L.push('');
    L.push('| File | Changes |');
    L.push('|------|---------|');
    for (const f of report.hotFiles) {
        L.push(`| \`${f.path}\` | ${f.changes} |`);
    }
    L.push('');
    L.push('---');
    L.push('');
    // Velocity
    L.push('## 4. Weekly Velocity');
    L.push('');
    if (report.velocity.length > 0) {
        L.push('| Week | Commits |');
        L.push('|------|---------|');
        for (const v of report.velocity) {
            const bar = '█'.repeat(Math.min(Math.round(v.commits / 2), 30));
            L.push(`| ${v.week} | ${v.commits} ${bar} |`);
        }
        const avgPerWeek = report.velocity.length > 0
            ? Math.round(report.velocity.reduce((sum, v) => sum + v.commits, 0) / report.velocity.length)
            : 0;
        L.push('');
        L.push(`**Average:** ${avgPerWeek} commits/week.`);
    }
    L.push('');
    L.push('---');
    L.push('');
    // Footer
    L.push(`**Tools used:** ${report.toolsUsed.join(', ')}`);
    L.push(`**Analysis time:** ${elapsed}s`);
    L.push('');
    L.push('*Generated by [VyuhLabs DXKit](https://www.npmjs.com/package/@vyuhlabs/dxkit)*');
    return L.join('\n');
}
//# sourceMappingURL=index.js.map