// cli/commands/release.ts — lightweight release readiness checks (SPEC-1069)
import { execFile } from 'node:child_process';
import { promisify } from 'node:util';
import { green, red, yellow } from '../colors.js';
const execFileAsync = promisify(execFile);
const RELEASE_BRANCHES = ['main', 'develop', 'release'];
export const releaseCommand = {
    name: 'release',
    description: 'Check lightweight release readiness',
    usage: 'planu release check [--json]',
    async run(args, flags) {
        const subcommand = args[0] ?? 'check';
        if (subcommand !== 'check') {
            process.stderr.write(`${red('Error:')} Unknown release subcommand "${subcommand}".\n`);
            process.stderr.write(`Usage: ${releaseCommand.usage}\n`);
            process.exitCode = 1;
            return;
        }
        const result = await checkReleaseReadiness(process.cwd());
        if (flags?.json) {
            process.stdout.write(JSON.stringify(result, null, 2) + '\n');
            if (!result.clean || !result.synced) {
                process.exitCode = 1;
            }
            return;
        }
        writeReleaseCheck(result);
        if (!result.clean || !result.synced) {
            process.exitCode = 1;
        }
    },
};
async function checkReleaseReadiness(cwd) {
    const problems = [];
    const status = await git(cwd, ['status', '--short']);
    const clean = status.trim().length === 0;
    if (!clean) {
        problems.push('working tree has uncommitted changes');
    }
    const head = (await git(cwd, ['rev-parse', 'HEAD'])).trim() || null;
    const branches = {};
    for (const branch of RELEASE_BRANCHES) {
        branches[branch] = await resolveRef(cwd, branch);
    }
    const branchValues = Object.values(branches);
    const synced = head !== null &&
        branchValues.every((value) => value !== null) &&
        branchValues.every((value) => value === head);
    if (!synced) {
        problems.push('main, develop, and release are not all synced to HEAD');
    }
    return { clean, synced, head, branches, problems };
}
async function resolveRef(cwd, branch) {
    const candidates = [branch, `origin/${branch}`];
    for (const candidate of candidates) {
        try {
            const value = (await git(cwd, ['rev-parse', candidate])).trim();
            if (value) {
                return value;
            }
        }
        catch {
            // Try next candidate.
        }
    }
    return null;
}
async function git(cwd, args) {
    const result = await execFileAsync('git', args, {
        cwd,
        maxBuffer: 1024 * 1024,
        timeout: 10_000,
    });
    return result.stdout;
}
function writeReleaseCheck(result) {
    if (result.clean && result.synced) {
        process.stdout.write(`${green('Release ready.')} main, develop, and release match HEAD.\n`);
        return;
    }
    process.stdout.write(`${yellow('Release not ready.')}\n`);
    for (const problem of result.problems) {
        process.stdout.write(`- ${problem}\n`);
    }
}
//# sourceMappingURL=release.js.map