// Copyright (c) 2026 Hellmai Ltd
// SPDX-License-Identifier: AGPL-3.0-only
/**
 * @file wu-claim-branch.ts
 * @description Branch-only mode claim workflow handler.
 *
 * WU-1649: Extracted from wu-claim.ts to reduce orchestration complexity.
 * All functions are mechanical extractions preserving original behavior.
 */
import { readFile } from 'node:fs/promises';
import { resolveIntegrationTarget } from '@lumenflow/core/integration-target';
import { parseYAML } from '@lumenflow/core/wu-yaml';
import { getGitForCwd } from '@lumenflow/core/git-adapter';
import { die, getErrorMessage } from '@lumenflow/core/error-handler';
import { LOG_PREFIX, COMMIT_FORMATS, CLAIMED_MODES, FILE_SYSTEM, } from '@lumenflow/core/wu-constants';
import { shouldSkipRemoteOperations } from '@lumenflow/core/micro-worktree';
import { emitMandatoryAgentAdvisory } from '@lumenflow/core/orchestration-advisory-loader';
import { updateWUYaml, addOrReplaceInProgressStatus, removeFromReadyAndAddToInProgressBacklog, maybeProgressInitiativeStatus, ensureCleanOrClaimOnlyWhenNoAuto, } from './wu-claim-state.js';
import { shouldPersistClaimMetadataOnBranch } from './wu-claim-state.js';
import { surfaceUnreadSignalsForDisplay, printCondensedClaimSummary } from './wu-claim-output.js';
const PREFIX = LOG_PREFIX.CLAIM;
/**
 * WU-2306: Branch claim mode label for operator-facing output.
 */
export function getBranchModeDisplayLabel(claimedMode) {
    return claimedMode === CLAIMED_MODES.BRANCH_PR
        ? 'Branch-PR (no worktree)'
        : 'Branch-Only (no worktree)';
}
/**
 * WU-2306: Mode-aware next-step guidance for branch claim flows.
 *
 * Branch-PR follows wu:prep -> wu:done in the active branch.
 * Branch-Only keeps legacy gates -> wu:done guidance.
 */
export function getBranchClaimNextSteps(id, claimedMode) {
    if (claimedMode === CLAIMED_MODES.BRANCH_PR) {
        return [
            '  1. Work on this branch in the main checkout',
            `  2. Run: pnpm wu:brief --id ${id} --client <client>  (REQUIRED — generates handoff prompt and records evidence)`,
            '  3. Implement changes per acceptance criteria',
            `  4. Run: pnpm wu:prep --id ${id}`,
            `  5. Run: pnpm wu:done --id ${id}  (creates PR in branch-pr mode)`,
        ];
    }
    return [
        '  1. Work on this branch in the main checkout',
        `  2. Run: pnpm wu:brief --id ${id} --client <client>  (REQUIRED — generates handoff prompt and records evidence)`,
        '  3. Implement changes per acceptance criteria',
        '  4. Run: pnpm gates',
        `  5. pnpm wu:done --id ${id}`,
    ];
}
export function getBranchClaimCommonMistakes(claimedMode) {
    const common = [`  - Don't manually edit WU YAML status fields`];
    if (claimedMode === CLAIMED_MODES.BRANCH_PR) {
        return [...common, `  - Don't skip wu:done and create the PR manually`];
    }
    return [...common, `  - Don't create PRs (trunk-based development)`];
}
/**
 * Execute branch-only mode claim workflow
 */
export async function claimBranchOnlyMode(ctx) {
    const { args, id, laneK, title, branch, WU_PATH, STATUS_PATH, BACKLOG_PATH, claimedMode, shouldCreateBranch, currentBranch, sessionId, updatedTitle, currentBranchForCloud, // WU-1590: For persisting claimed_branch
     } = ctx;
    const skipRemote = shouldSkipRemoteOperations();
    const integrationTarget = resolveIntegrationTarget();
    if (shouldCreateBranch) {
        // Create branch and switch to it from origin/main (avoids local main mutation)
        try {
            const branchStartPoint = skipRemote
                ? integrationTarget.mainBranch
                : integrationTarget.trackingRef;
            await getGitForCwd().createBranch(branch, branchStartPoint);
        }
        catch (error) {
            die(`Canonical claim state may be updated, but branch creation failed.\n\n` +
                `Error: ${getErrorMessage(error)}\n\n` +
                `Recovery:\n` +
                `  1. Run: git fetch ${integrationTarget.remote} ${integrationTarget.mainBranch}\n` +
                `  2. Retry: pnpm wu:claim --id ${id} --lane "${args.lane}"\n` +
                `  3. If needed, delete local branch: git branch -D ${branch}`);
        }
    }
    else if (currentBranch !== branch) {
        die(`Cloud branch-pr claim must run on the active branch.\n\n` +
            `Current branch: ${currentBranch}\n` +
            `Resolved branch: ${branch}\n\n` +
            `Switch to ${branch} and retry, or omit conflicting --branch flags.`);
    }
    let finalTitle = updatedTitle || title;
    const msg = COMMIT_FORMATS.CLAIM(id.toLowerCase(), laneK);
    const shouldPersistClaimMetadata = shouldPersistClaimMetadataOnBranch({
        claimedMode,
        noPush: Boolean(args.noPush),
        skipRemote,
    });
    if (shouldPersistClaimMetadata) {
        if (args.noAuto) {
            await ensureCleanOrClaimOnlyWhenNoAuto();
        }
        else {
            // WU-1211: updateWUYaml now returns {title, initiative}
            // WU-1590: Pass claimed_branch for branch-pr persistence
            const updateResult = await updateWUYaml(WU_PATH, id, args.lane, claimedMode, null, sessionId, null, currentBranchForCloud || null);
            finalTitle = updateResult.title || finalTitle;
            await addOrReplaceInProgressStatus(STATUS_PATH, id, finalTitle);
            await removeFromReadyAndAddToInProgressBacklog(BACKLOG_PATH, STATUS_PATH, id, finalTitle, args.lane);
            const filesToAdd = [WU_PATH, STATUS_PATH, BACKLOG_PATH];
            // WU-1211: Progress initiative status if needed
            if (updateResult.initiative) {
                const initProgress = await maybeProgressInitiativeStatus(process.cwd(), updateResult.initiative, id);
                if (initProgress.initPath) {
                    filesToAdd.push(initProgress.initPath);
                }
            }
            await getGitForCwd().add(filesToAdd);
        }
        await getGitForCwd().commit(msg);
    }
    if (args.noPush || skipRemote) {
        if (skipRemote && !args.noPush) {
            console.warn(`${PREFIX} Local-only mode (git.requireRemote=false): skipping origin push; claim is local-only.`);
        }
        else {
            console.warn(`${PREFIX} Warning: --no-push enabled. Claim is local-only and NOT visible to other agents.`);
        }
    }
    else {
        await getGitForCwd().push(integrationTarget.remote, branch, { setUpstream: true });
    }
    // Summary
    console.log(`\n${PREFIX} Claim recorded in ${getBranchModeDisplayLabel(claimedMode)}.`);
    const wuDisplay = finalTitle ? `- WU: ${id} — ${finalTitle}` : `- WU: ${id}`;
    console.log(wuDisplay);
    console.log(`- Lane: ${args.lane}`);
    console.log(`- Mode: ${getBranchModeDisplayLabel(claimedMode)}`);
    const refDisplay = args.noPush ? `- Commit: ${msg}` : `- Branch: ${branch}`;
    console.log(refDisplay);
    if (claimedMode === CLAIMED_MODES.BRANCH_ONLY) {
        console.log('\n⚠️  LIMITATION: Branch-Only mode does not support parallel WUs (WIP=1 across ALL lanes)');
    }
    console.log('Next: work on this branch in the main checkout.');
    // Emit mandatory agent advisory based on code_paths (WU-1324)
    const wuContent = await readFile(WU_PATH, { encoding: FILE_SYSTEM.UTF8 });
    const wuDoc = parseYAML(wuContent);
    const codePaths = wuDoc.code_paths || [];
    emitMandatoryAgentAdvisory(codePaths, id);
    printCondensedClaimSummary({
        nextSteps: getBranchClaimNextSteps(id, claimedMode),
        reminder: claimedMode === CLAIMED_MODES.BRANCH_PR
            ? 'Keep WU metadata under CLI control and let wu:done create the PR.'
            : 'Keep WU metadata under CLI control and stay trunk-based until wu:done completes.',
        id,
    });
    // WU-1473: Surface unread coordination signals so agents see pending messages
    // Fail-open: surfaceUnreadSignals never throws
    await surfaceUnreadSignalsForDisplay(process.cwd());
}
//# sourceMappingURL=wu-claim-branch.js.map