/**
 * studiograph admin audit-workspace — read-only health aggregator.
 *
 * Wraps `analyzeGraphHealth()` from src/services/graph-maintenance.ts —
 * the same service that powers the dashboard's health digest — and
 * emits a markdown report. The point isn't to surface anything new; it's
 * to give the owner a single command for the periodic sweep, instead of
 * running `studiograph lint`, `studiograph orphans`, and chasing broken
 * wikilinks by hand.
 *
 * Output is stdout by default (so it can be piped to `pbcopy`, `glow`,
 * or `tee somewhere.md`). `--out <path>` writes to disk and prints just
 * the summary table.
 */
import { Command } from 'commander';
import { intro, outro, log, spinner } from '@clack/prompts';
import { writeFileSync } from 'fs';
import { resolve } from 'path';
import { Workspace } from '../../../core/workspace.js';
import { WorkspaceManager } from '../../../core/workspace-manager.js';
import { analyzeGraphHealth, } from '../../../services/graph-maintenance.js';
export const adminAuditWorkspaceCommand = new Command('audit-workspace')
    .description('Read-only workspace health report (lint + orphans + stale + broken wikilinks)')
    .option('--out <path>', 'Write the markdown report to <path> instead of stdout')
    .option('--quiet', 'Suppress the intro/outro decorations (useful in pipes)')
    .action(async (opts) => {
    if (!opts.quiet)
        intro('Studiograph workspace audit');
    const workspace = new Workspace();
    if (!workspace.isWorkspace()) {
        if (!opts.quiet)
            outro('Not a Studiograph workspace. Run from your workspace root.');
        else
            console.error('Not a Studiograph workspace.');
        process.exit(1);
        return;
    }
    const config = await workspace.loadConfig();
    const gitUser = { id: 'system', name: 'system', email: 'system@local' };
    const manager = new WorkspaceManager(process.cwd(), config, gitUser);
    const spin = opts.quiet ? null : spinner();
    spin?.start('Aggregating health metrics');
    const report = await analyzeGraphHealth(manager);
    spin?.stop('Done');
    const markdown = renderMarkdown(report, config.team_name ?? 'workspace');
    if (opts.out) {
        const path = resolve(opts.out);
        writeFileSync(path, markdown, 'utf-8');
        if (!opts.quiet)
            log.success(`Wrote ${path}`);
        printSummary(report);
    }
    else {
        // Stdout path. clack's log helpers add prefixes that fight pipes, so
        // use plain console.log for the report and reserve clack for the
        // intro/outro framing (skipped under --quiet).
        console.log(markdown);
    }
    if (!opts.quiet)
        outro(`${report.summary.totalIssues} issue(s) across ${report.summary.totalEntities} entities.`);
});
function printSummary(report) {
    const s = report.summary;
    log.message(`Summary:\n` +
        `  entities:        ${s.totalEntities}\n` +
        `  missing fields:  ${s.missingFields}\n` +
        `  orphans:         ${s.orphanEntities}\n` +
        `  stale:           ${s.staleEntities}\n` +
        `  broken wikilinks: ${s.brokenWikilinks}\n` +
        `  total issues:    ${s.totalIssues}`);
}
/**
 * Render the report as a markdown document. Sections are emitted only
 * when they have content — an empty workspace produces a tight one-page
 * doc, a full audit produces a long one.
 */
export function renderMarkdown(report, workspaceName) {
    const s = report.summary;
    const lines = [];
    lines.push(`# Workspace audit — ${workspaceName}`);
    lines.push('');
    lines.push(`_Generated ${report.generatedAt}_`);
    lines.push('');
    lines.push('## Summary');
    lines.push('');
    lines.push('| Metric | Count |');
    lines.push('| --- | ---: |');
    lines.push(`| Entities | ${s.totalEntities} |`);
    lines.push(`| Total issues | ${s.totalIssues} |`);
    lines.push(`| Missing-field issues | ${s.missingFields} |`);
    lines.push(`| Orphan entities | ${s.orphanEntities} |`);
    lines.push(`| Stale entities (>30d) | ${s.staleEntities} |`);
    lines.push(`| Broken wikilinks | ${s.brokenWikilinks} |`);
    lines.push('');
    if (s.totalIssues === 0) {
        lines.push('No issues found.');
        return lines.join('\n') + '\n';
    }
    if (report.missingFields.length > 0) {
        lines.push('## Missing fields');
        lines.push('');
        for (const issue of report.missingFields) {
            lines.push(`- **${issue.entityType}** \`${issue.entityId}\` (${issue.repo}) — ${issue.missingFields.join(', ')}`);
        }
        lines.push('');
    }
    if (report.orphans.length > 0) {
        lines.push('## Orphans (zero inbound references)');
        lines.push('');
        for (const o of report.orphans) {
            lines.push(`- **${o.entityType}** \`${o.entityId}\` (${o.repo}) — ${o.name}`);
        }
        lines.push('');
    }
    if (report.stale.length > 0) {
        lines.push('## Stale entities (no edits in >30 days)');
        lines.push('');
        for (const st of report.stale) {
            lines.push(`- **${st.entityType}** \`${st.entityId}\` (${st.repo}) — ${st.name}, last touched ${st.lastUpdated} (${st.daysSinceUpdate}d ago)`);
        }
        lines.push('');
    }
    if (report.brokenLinks.length > 0) {
        lines.push('## Broken wikilinks');
        lines.push('');
        for (const bl of report.brokenLinks) {
            lines.push(`- **${bl.entityType}** \`${bl.entityId}\` (${bl.repo}) — ${bl.name} → \`[[${bl.brokenLink}]]\``);
        }
        lines.push('');
    }
    return lines.join('\n') + '\n';
}
//# sourceMappingURL=audit-workspace.js.map