"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
    for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.createWorkflowPublisher = createWorkflowPublisher;
const publisher_shared_1 = require("./publisher-shared");
const pending_planning_support_1 = require("./pending-planning-support");
const publisher_state_support_1 = require("./publisher-state-support");
const publisher_visible_support_1 = require("./publisher-visible-support");
__exportStar(require("./publisher-shared"), exports);
// biome-ignore lint/complexity/noExcessiveLinesPerFunction: Publisher sequencing stays explicit while workflow write paths migrate into one entrypoint.
function createWorkflowPublisher(input) {
    return {
        // biome-ignore lint/complexity/noExcessiveLinesPerFunction: Publish ordering must remain explicit while old workflow write paths are removed phase by phase.
        // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Publish ordering must remain explicit while old workflow write paths are removed phase by phase.
        async publishWorkflow(request) {
            (0, publisher_state_support_1.validateWorkflowPublishRequest)(request);
            const createdDependencyChanges = [];
            let createdIssue = null;
            let shouldRollbackCreatedDependencies = true;
            try {
                const initialComments = request.target.kind === "new_issue"
                    ? []
                    : await input.ticketTracker.listComments((0, publisher_state_support_1.resolveExistingTargetIssueId)(request.target), { timeline: "issue-only" });
                const currentWorkflowStateResolution = request.target.kind === "new_issue"
                    ? null
                    : (0, publisher_state_support_1.resolveWorkflowStateCommentFromComments)(initialComments, request.responseLanguage, request.invalidWorkflowStatePolicy);
                const currentWorkflowStateComment = currentWorkflowStateResolution?.kind === "found"
                    ? currentWorkflowStateResolution.comment
                    : null;
                const currentWorkflowState = currentWorkflowStateResolution?.kind === "found"
                    ? currentWorkflowStateResolution.workflowState
                    : null;
                if (request.target.kind !== "new_issue" &&
                    request.publishPrecondition !== undefined &&
                    !(0, publisher_state_support_1.publishPreconditionMatches)({
                        workflowStateComment: currentWorkflowStateComment,
                        workflowState: currentWorkflowState,
                        precondition: request.publishPrecondition,
                    })) {
                    const targetIssue = await input.ticketTracker.getIssue((0, publisher_state_support_1.resolveExistingTargetIssueId)(request.target));
                    return {
                        targetIssue,
                        publishStatus: "guard_rejected",
                        workflowStateComment: currentWorkflowStateComment,
                        visibleUpdateComment: null,
                        appliedDependencyChanges: [],
                        workflowProjectionApplied: false,
                        targetWorkflowState: currentWorkflowState,
                        targetWorkflowProjection: targetIssue.workflowState,
                        scannedCommentCursor: currentWorkflowState?.lastScannedCommentCursor ?? null,
                        targetClosed: false,
                        currentWorkflowStateComment,
                        currentWorkflowState,
                    };
                }
                const targetIssue = await (0, publisher_state_support_1.resolveTargetIssue)(input, request);
                if (request.target.kind === "new_issue") {
                    createdIssue = targetIssue;
                }
                const targetIssueLabelsAreFresh = areTargetIssueLabelsFreshAfterResolution(request);
                const appliedDependencyChanges = await (0, publisher_state_support_1.applyDependencyChanges)({
                    publisher: input,
                    targetIssueId: targetIssue.id,
                    changes: request.dependencyChanges ?? [],
                    createdDependencyChanges,
                });
                let targetWorkflowState = request.workflowState;
                const appendWorkflowStateComment = shouldAppendWorkflowStateComment(request);
                const prePublishCursor = (0, publisher_visible_support_1.resolvePrePublishCommentCursor)(request.commentCursorPolicy, targetWorkflowState);
                let workflowProjectionApplied = false;
                const deferWorkflowStateCommit = (0, publisher_state_support_1.shouldDeferWorkflowStateCommit)(request);
                const workflowStateForInitialPublish = targetWorkflowState === null
                    ? null
                    : prePublishCursor.known
                        ? (0, publisher_visible_support_1.applyScannedCommentCursor)(targetWorkflowState, prePublishCursor.cursor)
                        : targetWorkflowState;
                const provisionalWorkflowStateComment = workflowStateForInitialPublish === null || deferWorkflowStateCommit
                    ? null
                    : (await (0, publisher_state_support_1.upsertWorkflowStateComment)({
                        publisher: input,
                        issueId: targetIssue.id,
                        workflowState: workflowStateForInitialPublish,
                        append: appendWorkflowStateComment,
                        invalidWorkflowStatePolicy: request.invalidWorkflowStatePolicy,
                        responseLanguage: request.responseLanguage,
                    })).comment;
                targetWorkflowState = workflowStateForInitialPublish;
                const workflowStateCommentForCursor = deferWorkflowStateCommit
                    ? currentWorkflowStateComment
                    : (provisionalWorkflowStateComment ?? currentWorkflowStateComment);
                const workflowStateCommentForInitialVisibleUpdate = appendWorkflowStateComment && deferWorkflowStateCommit
                    ? null
                    : workflowStateCommentForCursor;
                const visibleWorkflowStateForInitialPublish = request.visibleWorkflowState !== undefined
                    ? request.visibleWorkflowState
                    : (targetWorkflowState ?? currentWorkflowState);
                workflowProjectionApplied = await (0, publisher_state_support_1.maybeSyncWorkflowProjection)({
                    publisher: input,
                    targetIssueId: targetIssue.id,
                    targetIssue,
                    targetIssueLabelsAreFresh,
                    projection: request.workflowProjection,
                });
                const visibleUpdatePublication = request.visibleUpdate === undefined || request.visibleUpdate === null
                    ? {
                        publishedComment: null,
                        commentForRefresh: null,
                    }
                    : await (0, publisher_visible_support_1.publishVisibleUpdate)({
                        publisher: input,
                        issueId: targetIssue.id,
                        visibleUpdate: request.visibleUpdate,
                        visibleUpdateDedupeCursor: request.visibleUpdateDedupeCursor,
                        commentCursorPolicy: request.commentCursorPolicy,
                        workflowState: visibleWorkflowStateForInitialPublish,
                        workflowStateComment: workflowStateCommentForInitialVisibleUpdate,
                        initialComments,
                        responseLanguage: request.responseLanguage,
                    });
                const scannedCommentCursor = prePublishCursor.known
                    ? prePublishCursor.cursor
                    : await (0, publisher_visible_support_1.resolveFinalCommentCursor)({
                        publisher: input,
                        issueId: targetIssue.id,
                        policy: request.commentCursorPolicy,
                        visibleUpdateComment: visibleUpdatePublication.publishedComment,
                        workflowStateComment: workflowStateCommentForCursor,
                        initialComments,
                    });
                const finalWorkflowState = targetWorkflowState === null
                    ? null
                    : (0, publisher_visible_support_1.applyScannedCommentCursor)(targetWorkflowState, scannedCommentCursor);
                const finalizedCurrentWorkflowState = appendWorkflowStateComment && finalWorkflowState !== null
                    ? (0, pending_planning_support_1.withoutPendingPlanningState)(finalWorkflowState)
                    : null;
                const currentCommentsForDeferredCommit = finalWorkflowState === null || !deferWorkflowStateCommit
                    ? null
                    : await input.ticketTracker.listComments(targetIssue.id, {
                        timeline: "issue-only",
                    });
                const finalWorkflowStateForCommit = finalWorkflowState === null || !deferWorkflowStateCommit
                    ? finalWorkflowState
                    : (0, publisher_visible_support_1.maybeRefreshDeferredAiRunBudget)({
                        workflowState: finalWorkflowState,
                        initialComments,
                        currentComments: currentCommentsForDeferredCommit ?? initialComments,
                        responseLanguage: request.responseLanguage,
                    });
                const workflowStateComment = finalWorkflowStateForCommit === null
                    ? null
                    : deferWorkflowStateCommit
                        ? (await (0, publisher_state_support_1.upsertWorkflowStateComment)({
                            publisher: input,
                            issueId: targetIssue.id,
                            workflowState: finalWorkflowStateForCommit,
                            append: appendWorkflowStateComment,
                            invalidWorkflowStatePolicy: request.invalidWorkflowStatePolicy,
                            responseLanguage: request.responseLanguage,
                        })).comment
                        : (0, publisher_visible_support_1.cursorEquals)(targetWorkflowState?.lastScannedCommentCursor ?? null, finalWorkflowStateForCommit.lastScannedCommentCursor)
                            ? provisionalWorkflowStateComment
                            : (await (0, publisher_state_support_1.upsertWorkflowStateComment)({
                                publisher: input,
                                issueId: targetIssue.id,
                                workflowState: finalWorkflowStateForCommit,
                                append: appendWorkflowStateComment,
                                invalidWorkflowStatePolicy: request.invalidWorkflowStatePolicy,
                                responseLanguage: request.responseLanguage,
                            })).comment;
                targetWorkflowState = finalWorkflowStateForCommit;
                const refreshedVisibleUpdateComment = await repairPublishedWorkflowComments({
                    publisher: input,
                    targetIssueId: targetIssue.id,
                    appendWorkflowStateComment,
                    deferWorkflowStateCommit,
                    visibleUpdate: request.visibleUpdate,
                    visibleUpdatePublication,
                    currentWorkflowStateComment,
                    finalizedCurrentWorkflowState,
                    workflowState: finalWorkflowStateForCommit,
                    visibleWorkflowState: request.visibleWorkflowState,
                    workflowStateComment,
                    responseLanguage: request.responseLanguage,
                });
                const publicVisibleUpdateComment = visibleUpdatePublication.publishedComment === null
                    ? null
                    : refreshedVisibleUpdateComment;
                let targetClosed = false;
                if (request.terminalAction?.kind === "close") {
                    shouldRollbackCreatedDependencies = false;
                    try {
                        await input.ticketTracker.closeIssue(targetIssue.id);
                        targetClosed = true;
                    }
                    catch (error) {
                        throw new publisher_shared_1.WorkflowTerminalActionError({
                            action: request.terminalAction.kind,
                            targetIssueId: targetIssue.id,
                            cause: error,
                        });
                    }
                    const postCloseWorkflowProjection = request.terminalAction.postCloseWorkflowProjection;
                    if (postCloseWorkflowProjection !== undefined) {
                        try {
                            workflowProjectionApplied =
                                (await (0, publisher_state_support_1.maybeSyncWorkflowProjection)({
                                    publisher: input,
                                    targetIssueId: targetIssue.id,
                                    targetIssue,
                                    targetIssueLabelsAreFresh,
                                    projection: postCloseWorkflowProjection,
                                })) || workflowProjectionApplied;
                        }
                        catch {
                            // Preserve the closed state even if label cleanup fails afterward.
                        }
                    }
                    const postCloseDependencyChanges = request.terminalAction.postCloseDependencyChanges ?? [];
                    if (postCloseDependencyChanges.length > 0) {
                        appliedDependencyChanges.push(...(await (0, publisher_state_support_1.applyDependencyChanges)({
                            publisher: input,
                            targetIssueId: targetIssue.id,
                            changes: postCloseDependencyChanges,
                            createdDependencyChanges,
                        })));
                    }
                }
                await (0, publisher_state_support_1.acknowledgeScannedActionableCommentsFromPolicy)({
                    publisher: input,
                    initialComments,
                    currentWorkflowState,
                    nextWorkflowState: targetWorkflowState,
                    commentCursorPolicy: request.commentCursorPolicy,
                });
                return {
                    targetIssue,
                    publishStatus: "applied",
                    workflowStateComment,
                    visibleUpdateComment: publicVisibleUpdateComment,
                    appliedDependencyChanges,
                    workflowProjectionApplied,
                    targetWorkflowState,
                    targetWorkflowProjection: (0, publisher_state_support_1.resolveTargetWorkflowProjection)({
                        targetIssue,
                        workflowProjection: request.workflowProjection,
                    }),
                    scannedCommentCursor,
                    targetClosed,
                    currentWorkflowStateComment: workflowStateComment,
                    currentWorkflowState: targetWorkflowState,
                };
            }
            catch (error) {
                const cleanupErrors = [];
                if (shouldRollbackCreatedDependencies) {
                    try {
                        await (0, publisher_state_support_1.rollbackCreatedDependencies)({
                            publisher: input,
                            changes: createdDependencyChanges,
                        });
                    }
                    catch (cleanupError) {
                        cleanupErrors.push(cleanupError);
                    }
                }
                if (createdIssue !== null &&
                    request.newIssueFailurePolicy === "close_created_internal_issue") {
                    try {
                        await input.ticketTracker.closeIssue(createdIssue.id);
                    }
                    catch (cleanupError) {
                        cleanupErrors.push(cleanupError);
                    }
                }
                (0, publisher_visible_support_1.attachWorkflowPublishCleanupErrors)(error, cleanupErrors);
                throw error;
            }
        },
    };
}
function areTargetIssueLabelsFreshAfterResolution(request) {
    if (request.target.kind === "new_issue") {
        return true;
    }
    if (request.trackerFields !== undefined) {
        return true;
    }
    return request.target.preloadedIssue === undefined;
}
function shouldAppendWorkflowStateComment(request) {
    return request.appendCanonicalWorkflowStateComment === true;
}
async function repairPublishedWorkflowComments(input) {
    const workflowStateForVisibleUpdate = input.visibleWorkflowState !== undefined
        ? input.visibleWorkflowState
        : input.workflowState;
    const refreshedVisibleUpdateComment = workflowStateForVisibleUpdate === null || input.visibleUpdate == null
        ? input.visibleUpdatePublication.commentForRefresh
        : input.deferWorkflowStateCommit || input.appendWorkflowStateComment
            ? await refreshVisibleUpdateCommentDuringRepair({
                publisher: input.publisher,
                visibleUpdate: input.visibleUpdate,
                visibleUpdateComment: input.visibleUpdatePublication.commentForRefresh,
                workflowState: workflowStateForVisibleUpdate,
                workflowStateComment: input.workflowStateComment,
                responseLanguage: input.responseLanguage,
                bestEffort: input.appendWorkflowStateComment,
            })
            : input.visibleUpdatePublication.commentForRefresh;
    if (input.appendWorkflowStateComment &&
        input.currentWorkflowStateComment !== null &&
        input.finalizedCurrentWorkflowState !== null) {
        await finalizeOldCanonicalCommentBestEffort({
            publisher: input.publisher,
            targetIssueId: input.targetIssueId,
            currentWorkflowStateComment: input.currentWorkflowStateComment,
            workflowState: input.finalizedCurrentWorkflowState,
            responseLanguage: input.responseLanguage,
        });
    }
    return refreshedVisibleUpdateComment;
}
async function refreshVisibleUpdateCommentDuringRepair(input) {
    if (!input.bestEffort) {
        return (0, publisher_visible_support_1.maybeRefreshVisibleUpdateComment)(input);
    }
    try {
        return await (0, publisher_visible_support_1.maybeRefreshVisibleUpdateComment)(input);
    }
    catch {
        return input.visibleUpdateComment;
    }
}
async function finalizeOldCanonicalCommentBestEffort(input) {
    try {
        await (0, publisher_state_support_1.updateWorkflowStateCommentById)({
            publisher: input.publisher,
            issueId: input.targetIssueId,
            commentId: input.currentWorkflowStateComment.id,
            workflowState: input.workflowState,
            responseLanguage: input.responseLanguage,
        });
    }
    catch {
        // Preserve the newly appended canonical even if history repair fails.
    }
}
