#!/usr/bin/env node
// Copyright (c) 2026 Hellmai Ltd
// SPDX-License-Identifier: AGPL-3.0-only
/**
 * Review a WU worktree against the configured integration target.
 *
 * WU-2790: Enterprise users need a first-class pre-done review path that
 * respects git.mainBranch/defaultRemote instead of assuming origin/main.
 */
import path from 'node:path';
import { existsSync } from 'node:fs';
import { createGitForPath, getGitForCwd } from '@lumenflow/core/git-adapter';
import { createWUParser, WU_OPTIONS } from '@lumenflow/core/arg-parser';
import { resolveIntegrationTarget } from '@lumenflow/core/integration-target';
import { getConfig } from '@lumenflow/core/config';
import { die } from '@lumenflow/core/error-handler';
import { LOG_PREFIX, EMOJI, EXIT_CODES, PATTERNS } from '@lumenflow/core/wu-constants';
import { getGitDiff } from './git-diff.js';
import { detectWorktreePath } from './wu-preflight.js';
import { runCLI } from './cli-entry-point.js';
const REVIEW_OPTIONS = {
    nameOnly: {
        name: 'name-only',
        flags: '--name-only',
        description: 'Show only changed file paths',
    },
    stat: {
        name: 'stat',
        flags: '--stat',
        description: 'Show diffstat output',
    },
    patch: {
        name: 'patch',
        flags: '--patch',
        description: 'Show full patch output',
    },
};
function shouldSkipRemoteSync(config = getConfig()) {
    return config.git.requireRemote === false;
}
export function parseWuReviewArgs(argv = process.argv) {
    const originalArgv = process.argv;
    try {
        process.argv = argv;
        const args = createWUParser({
            name: 'wu-review',
            description: 'Review a WU worktree against the configured integration target before wu:done.',
            options: [WU_OPTIONS.id, WU_OPTIONS.worktree, ...Object.values(REVIEW_OPTIONS)],
            required: ['id'],
            allowPositionalId: true,
        });
        return {
            id: String(args.id).toUpperCase(),
            worktree: typeof args.worktree === 'string' ? args.worktree : undefined,
            nameOnly: args.nameOnly === true,
            stat: args.stat === true,
            patch: args.patch === true,
        };
    }
    finally {
        process.argv = originalArgv;
    }
}
export async function resolveReviewBaseRef(options = {}) {
    const config = options.config ?? getConfig();
    const integrationTarget = resolveIntegrationTarget(config);
    const git = options.gitAdapter ?? (options.baseDir ? createGitForPath(options.baseDir) : getGitForCwd());
    if (!shouldSkipRemoteSync(config)) {
        try {
            await git.fetch(integrationTarget.remote, integrationTarget.mainBranch);
        }
        catch {
            // Best-effort fetch: fall back to cached tracking ref for review mode.
        }
    }
    const targetRef = shouldSkipRemoteSync(config)
        ? integrationTarget.mainBranch
        : integrationTarget.trackingRef;
    return (await git.mergeBase(targetRef, 'HEAD')).trim();
}
function assertValidWuId(id) {
    if (!PATTERNS.WU_ID.test(id)) {
        die(`Invalid WU ID format: ${id}. Expected WU-NNN`);
    }
}
function resolveReviewWorktreePath(id, requestedWorktree) {
    const resolvedPath = requestedWorktree || detectWorktreePath(id);
    if (!resolvedPath) {
        die(`Could not determine a worktree for ${id}.\n\n` +
            `Run from the WU worktree or pass --worktree <path>.`);
    }
    const absolutePath = path.resolve(resolvedPath);
    if (!existsSync(absolutePath)) {
        die(`Worktree does not exist: ${absolutePath}`);
    }
    return absolutePath;
}
function printReviewResult(result) {
    if (!result.success) {
        die(result.error || 'wu:review failed');
    }
    if (result.files) {
        result.files.forEach((filePath) => console.log(filePath));
        return;
    }
    if (result.stat) {
        console.log(result.stat);
        return;
    }
    if (result.diff) {
        console.log(result.diff);
        return;
    }
    console.log('No differences.');
}
/**
 * WU-2790: Emit a short "open in IDE" hint block so non-technical reviewers
 * (e.g. a product owner on a PO sign-off) have a copy-pasteable path to the
 * worktree folder plus a suggested IDE command based on their current shell
 * context. Keeps the output scannable without mandating a specific editor.
 */
export function formatOpenInIdeHint(worktreePath, termProgram) {
    const env = typeof termProgram === 'string' ? termProgram : '';
    const lines = ['Review options:', `  Terminal diff:   pnpm wu:review --id <WU-ID>`];
    if (env.toLowerCase() === 'vscode') {
        lines.push(`  VS Code:         code ${worktreePath}`);
    }
    else if (env.toLowerCase().startsWith('cursor')) {
        lines.push(`  Cursor:          cursor ${worktreePath}`);
    }
    else {
        lines.push(`  VS Code:         code ${worktreePath}`);
        lines.push(`  Cursor:          cursor ${worktreePath}`);
    }
    lines.push(`  Any IDE:         cd ${worktreePath}   (use the Source Control panel)`);
    return lines;
}
export async function main() {
    const args = parseWuReviewArgs();
    assertValidWuId(args.id);
    const config = getConfig();
    const integrationTarget = resolveIntegrationTarget(config);
    const worktreePath = resolveReviewWorktreePath(args.id, args.worktree);
    const baseRef = await resolveReviewBaseRef({ baseDir: worktreePath, config });
    const showNameOnly = args.nameOnly === true;
    const showStat = args.patch === true ? false : args.stat === true || !showNameOnly;
    console.log(`${LOG_PREFIX.DONE} ${EMOJI.INFO} Reviewing ${args.id}`);
    console.log(`${LOG_PREFIX.DONE} Worktree: ${worktreePath}`);
    console.log(`${LOG_PREFIX.DONE} Base: ${baseRef} (merge-base vs ${shouldSkipRemoteSync(config) ? integrationTarget.mainBranch : integrationTarget.trackingRef})`);
    console.log('');
    for (const line of formatOpenInIdeHint(worktreePath, process.env.TERM_PROGRAM)) {
        console.log(`${LOG_PREFIX.DONE} ${line}`);
    }
    console.log('');
    const result = await getGitDiff({
        baseDir: worktreePath,
        ref: baseRef,
        nameOnly: showNameOnly,
        stat: showStat,
    });
    printReviewResult(result);
    process.exit(EXIT_CODES.SUCCESS);
}
if (import.meta.main) {
    void runCLI(main);
}
//# sourceMappingURL=wu-review.js.map