"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.prepareMergeIntegrationPreflight = prepareMergeIntegrationPreflight;
const catalog_1 = require("../../i18n/catalog");
const types_1 = require("../../worker/types");
const run_context_1 = require("../../workflows/run-context");
const run_state_helpers_1 = require("./run-state-helpers");
const issue_branch_target_1 = require("./issue-branch-target");
const types_2 = require("./types");
async function prepareMergeIntegrationPreflight(input) {
    if (!shouldPrepareMergeIntegration(input.preparation)) {
        return input.preparation;
    }
    if (input.preparation.workflowState?.mergeContext !== undefined) {
        return withMergeContext(input.preparation, input.preparation.workflowState.mergeContext);
    }
    const baseBranch = (0, issue_branch_target_1.resolveIssueRunBaseBranch)(input.preparation.workflowState);
    if (await input.context.gitRepository.hasChanges(input.workspace.path)) {
        return toHumanHandoff(input.preparation, {
            summary: (0, run_state_helpers_1.buildWorkspaceSyncBlockedSummary)({
                responseLanguage: input.context.config.i18n.defaultLanguage,
                reason: "dirty_workspace",
                conflictedFiles: [],
            }),
        });
    }
    try {
        const result = await input.context.gitRepository.mergeSourceBranchIntoBranch({
            workspacePath: input.workspace.path,
            branchName: input.workspace.branchName,
            sourceBranchName: baseBranch,
        });
        if (result.kind === "merged") {
            try {
                await input.context.gitRepository.pushBranch(input.workspace.path, input.workspace.branchName, { hookContext: "worker" });
            }
            catch {
                return toHumanHandoff(input.preparation, {
                    summary: (0, catalog_1.translate)(input.context.config.i18n.defaultLanguage, "run.mergeIntegration.basePushFailed", { baseBranch }),
                });
            }
        }
        return withMergeContext(input.preparation, {
            baseBranch,
            baseCommitOid: result.sourceCommitOid,
            status: "clean",
            conflictedFiles: [],
        });
    }
    catch (error) {
        if ((0, run_state_helpers_1.isWorkspaceSyncBlockedError)(error) &&
            error.reason === "dirty_workspace") {
            return toHumanHandoff(input.preparation, {
                summary: (0, run_state_helpers_1.buildWorkspaceSyncBlockedSummary)({
                    responseLanguage: input.context.config.i18n.defaultLanguage,
                    reason: "dirty_workspace",
                    conflictedFiles: [],
                }),
            });
        }
        if ((0, run_state_helpers_1.isWorkspaceSyncBlockedError)(error) &&
            error.reason === "merge_conflict") {
            return withMergeContext(input.preparation, {
                baseBranch,
                baseCommitOid: error.sourceCommitOid ??
                    (await input.context.gitRepository.getRemoteBranchHeadCommitOid(input.workspace.path, baseBranch)),
                status: "conflicted",
                conflictedFiles: [...(error.conflictedFiles ?? [])],
            });
        }
        throw error;
    }
}
function shouldPrepareMergeIntegration(preparation) {
    return (preparation.workflowState?.workflowSurface === "merge" &&
        preparation.workflowState.pendingPlanningIntent === "replan");
}
function toHumanHandoff(preparation, input) {
    return {
        ...preparation,
        kind: "handoff_to_human",
        summary: input.summary,
        needsHumanReason: types_2.WORKER_NEEDS_HUMAN_REASONS.question,
    };
}
function withMergeContext(preparation, mergeContext) {
    const workflowState = preparation.workflowState === null
        ? null
        : {
            ...preparation.workflowState,
            mergeContext,
        };
    return {
        ...preparation,
        workflow: {
            ...preparation.workflow,
            mergeContext,
            state: (0, run_context_1.sanitizeWorkerVisibleWorkflowState)(workflowState, {
                includeDependencySyncState: preparation.workflow.mode === types_1.WORKER_RUN_MODES.workflowPlan,
            }),
        },
        workflowState,
    };
}
