"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveWorkflowCommandOptionValueKind = void 0;
exports.normalizeWorkflowCommandOptions = normalizeWorkflowCommandOptions;
exports.parseWorkflowOptionTokens = parseWorkflowOptionTokens;
exports.consumeWorkflowOptionToken = consumeWorkflowOptionToken;
exports.parseWorkflowOptionTail = parseWorkflowOptionTail;
exports.pickWorkflowCommandUpdateFields = pickWorkflowCommandUpdateFields;
exports.normalizeWorkflowCommandUpdateDraftFields = normalizeWorkflowCommandUpdateDraftFields;
exports.compactSideWorkflowTemplateSelectors = compactSideWorkflowTemplateSelectors;
exports.compactWorkflowCommandUpdateFields = compactWorkflowCommandUpdateFields;
exports.hasWorkflowCommandUpdateFieldValue = hasWorkflowCommandUpdateFieldValue;
exports.assignWorkflowCommandCoreUpdateFields = assignWorkflowCommandCoreUpdateFields;
// biome-ignore lint/nursery/noExcessiveLinesPerFile: Workflow command parsing remains centralized so option interactions stay auditable.
const comment_command_overrides_1 = require("./comment-command-overrides");
const issue_override_option_registry_1 = require("./issue-override-option-registry");
const types_1 = require("./types");
const template_bindings_1 = require("./template-bindings");
const workflow_option_parse_shared_1 = require("./workflow-option-parse-shared");
const workflow_command_option_specs_1 = require("./workflow-command-option-specs");
const workflow_schedule_option_normalizer_1 = require("./workflow-schedule-option-normalizer");
const workflow_recurring_auto_stop_option_normalizer_1 = require("./workflow-recurring-auto-stop-option-normalizer");
const workflow_option_value_kinds_1 = require("./workflow-option-value-kinds");
var workflow_option_value_kinds_2 = require("./workflow-option-value-kinds");
Object.defineProperty(exports, "resolveWorkflowCommandOptionValueKind", { enumerable: true, get: function () { return workflow_option_value_kinds_2.resolveWorkflowCommandOptionValueKind; } });
function normalizeWorkflowCommandOptions(input) {
    if (input.kind === "draft") {
        return normalizeWorkflowCommandUpdateDraft(input.draft);
    }
    if (input.kind === "tail") {
        return normalizeWorkflowCommandOptionTokens(tokenizeWorkflowCommandTail(input.commandTail), input.bodyAfterCommand ?? "");
    }
    return normalizeWorkflowCommandOptionTokens(input.tokens, input.bodyAfterCommand ?? "");
}
function parseWorkflowOptionTokens(tokens, bodyAfterCommand = "") {
    return normalizeWorkflowCommandOptionTokens(tokens, bodyAfterCommand);
}
function consumeWorkflowOptionToken(tokens, index) {
    const token = tokens[index];
    if (token === undefined) {
        return undefined;
    }
    const valueKind = (0, workflow_option_value_kinds_1.resolveWorkflowCommandOptionValueKind)(token);
    if (valueKind === undefined) {
        return undefined;
    }
    if (valueKind === "none") {
        return { consumedTokens: 1 };
    }
    const nextToken = tokens[index + 1];
    if (nextToken === undefined) {
        return { consumedTokens: 1 };
    }
    if (valueKind === "required") {
        return { consumedTokens: 2 };
    }
    if (nextToken.startsWith("--")) {
        return { consumedTokens: 1 };
    }
    return {
        consumedTokens: (0, workflow_option_value_kinds_1.resolveWorkflowCommandOptionValueKind)(nextToken) === undefined ? 2 : 1,
    };
}
function parseWorkflowOptionTail(commandTail, bodyAfterCommand = "") {
    return normalizeWorkflowCommandOptions({
        kind: "tail",
        commandTail,
        bodyAfterCommand,
    });
}
function pickWorkflowCommandUpdateFields(draft) {
    const fields = {};
    assignWorkflowCommandUpdateFields(fields, draft);
    return fields;
}
function normalizeWorkflowCommandUpdateDraftFields(draft) {
    const normalized = normalizeWorkflowCommandUpdateDraft(draft);
    if (normalized.kind === "invalid") {
        return normalized;
    }
    return {
        kind: "update",
        fields: pickWorkflowCommandUpdateFields(normalized),
        bodyAfterCommand: normalized.bodyAfterCommand,
    };
}
function compactSideWorkflowTemplateSelectors(input, mapSelector = (selector) => selector) {
    if (input == null) {
        return undefined;
    }
    const selectors = {};
    for (const surface of template_bindings_1.SIDE_WORKFLOW_TEMPLATE_SURFACES) {
        const selector = input[surface];
        if (selector != null) {
            selectors[surface] = mapSelector(selector, surface);
        }
    }
    return Object.keys(selectors).length === 0 ? undefined : selectors;
}
function compactWorkflowCommandUpdateFields(input) {
    const fields = {};
    if (input.workflowSelection != null) {
        fields.workflowSelection = input.workflowSelection;
    }
    const workflowTemplateSelectors = compactSideWorkflowTemplateSelectors(input.workflowTemplateSelectors);
    if (workflowTemplateSelectors !== undefined) {
        fields.workflowTemplateSelectors = workflowTemplateSelectors;
    }
    if (input.schedule != null) {
        fields.schedule = input.schedule;
    }
    if (input.scheduledRun != null) {
        fields.scheduledRun = input.scheduledRun;
    }
    if (input.firstRun != null) {
        fields.firstRun = input.firstRun;
    }
    if (input.recurringAutoStop != null) {
        fields.recurringAutoStop = input.recurringAutoStop;
    }
    if (input.baseBranch != null) {
        fields.baseBranch = input.baseBranch;
    }
    if (input.configOverridePatch != null) {
        fields.configOverridePatch = input.configOverridePatch;
    }
    return fields;
}
function hasWorkflowCommandUpdateFieldValue(input) {
    const fields = compactWorkflowCommandUpdateFields(input);
    return (fields.workflowSelection !== undefined ||
        fields.workflowTemplateSelectors !== undefined ||
        fields.schedule !== undefined ||
        fields.scheduledRun !== undefined ||
        fields.firstRun !== undefined ||
        fields.recurringAutoStop !== undefined ||
        fields.baseBranch !== undefined ||
        fields.configOverridePatch !== undefined);
}
function normalizeWorkflowCommandUpdateDraft(draft) {
    const normalizedDraft = {
        bodyAfterCommand: draft.bodyAfterCommand ?? "",
    };
    assignWorkflowCommandUpdateFields(normalizedDraft, draft);
    return normalizeWorkflowCommandUpdate(normalizedDraft);
}
function tokenizeWorkflowCommandTail(commandTail) {
    const tokens = [];
    let current = "";
    let quote = null;
    for (let index = 0; index < commandTail.length; index += 1) {
        const char = commandTail[index];
        if (char === undefined) {
            continue;
        }
        if (quote !== null) {
            if (char === quote) {
                quote = null;
            }
            else {
                current += char;
            }
            continue;
        }
        if (char === '"' || char === "'") {
            quote = char;
            continue;
        }
        if (/\s/u.test(char)) {
            if (current.length > 0) {
                tokens.push(current);
                current = "";
            }
            continue;
        }
        current += char;
    }
    if (current.length > 0) {
        tokens.push(current);
    }
    return tokens;
}
function normalizeWorkflowCommandOptionTokens(tokens, bodyAfterCommand) {
    const parsed = parseWorkflowCommandTokens(tokens);
    const normalizedBodyAfterCommand = mergeInlineTrailingText(parsed.inlineTrailingText, bodyAfterCommand);
    if (parsed.kind === "invalid") {
        return {
            kind: "invalid",
            reason: parsed.reason,
            bodyAfterCommand: normalizedBodyAfterCommand,
        };
    }
    const normalizedDraft = {
        bodyAfterCommand: normalizedBodyAfterCommand,
    };
    assignWorkflowCommandUpdateFields(normalizedDraft, parsed);
    return normalizeWorkflowCommandUpdate(normalizedDraft);
}
function normalizeWorkflowCommandUpdate(draft) {
    if (draft.workflowTemplateSelectors?.followup !== undefined) {
        return {
            kind: "invalid",
            reason: "invalid-option-value",
            bodyAfterCommand: draft.bodyAfterCommand,
        };
    }
    if (!hasWorkflowCommandUpdateFieldValue(draft)) {
        return {
            kind: "invalid",
            reason: "missing-options",
            bodyAfterCommand: draft.bodyAfterCommand,
        };
    }
    if (draft.bodyAfterCommand.trim().length > 0 &&
        hasUnsupportedCommandBodyTarget(draft)) {
        return {
            kind: "invalid",
            reason: "unsupported-command-body",
            bodyAfterCommand: draft.bodyAfterCommand,
        };
    }
    if (draft.firstRun !== undefined &&
        (draft.schedule === undefined ||
            draft.schedule.mode === "off" ||
            draft.scheduledRun !== undefined)) {
        return {
            kind: "invalid",
            reason: "conflicting-schedule-options",
            bodyAfterCommand: draft.bodyAfterCommand,
        };
    }
    if (draft.recurringAutoStop !== undefined &&
        (draft.scheduledRun !== undefined || draft.schedule?.mode === "off")) {
        return {
            kind: "invalid",
            reason: "conflicting-schedule-options",
            bodyAfterCommand: draft.bodyAfterCommand,
        };
    }
    const result = {
        kind: "update",
        bodyAfterCommand: draft.bodyAfterCommand,
    };
    assignWorkflowCommandUpdateFields(result, draft);
    return result;
}
function hasUnsupportedCommandBodyTarget(draft) {
    return ((draft.schedule !== undefined && draft.schedule.mode !== "off") ||
        (draft.scheduledRun !== undefined && draft.scheduledRun.mode !== "off") ||
        draft.firstRun !== undefined ||
        draft.recurringAutoStop !== undefined ||
        hasRecurringConfigOverride(draft.configOverridePatch));
}
function hasRecurringConfigOverride(patch) {
    return (patch?.entries.some((entry) => entry.path.startsWith("recurring.")) ?? false);
}
function assignWorkflowCommandCoreUpdateFields(target, source) {
    if (source.workflowSelection !== undefined) {
        target.workflowSelection = source.workflowSelection;
    }
    if (source.workflowTemplateSelectors !== undefined) {
        target.workflowTemplateSelectors = {
            ...target.workflowTemplateSelectors,
            ...source.workflowTemplateSelectors,
        };
    }
    if (source.schedule !== undefined) {
        target.schedule = source.schedule;
        delete target.scheduledRun;
        if (source.schedule.mode === "off") {
            delete target.recurringAutoStop;
        }
        if (source.firstRun === undefined) {
            delete target.firstRun;
        }
    }
    if (source.scheduledRun !== undefined) {
        target.scheduledRun = source.scheduledRun;
        delete target.firstRun;
        delete target.recurringAutoStop;
        if (source.scheduledRun.mode !== "off") {
            delete target.schedule;
        }
    }
    if (source.firstRun !== undefined) {
        target.firstRun = source.firstRun;
        delete target.scheduledRun;
    }
    if (source.recurringAutoStop !== undefined) {
        target.recurringAutoStop = source.recurringAutoStop;
    }
    if (source.baseBranch !== undefined) {
        target.baseBranch = source.baseBranch;
    }
}
function assignWorkflowCommandUpdateFields(target, source) {
    assignWorkflowCommandCoreUpdateFields(target, source);
    if (source.configOverridePatch !== undefined) {
        target.configOverridePatch = source.configOverridePatch;
    }
}
function mergeInlineTrailingText(inlineTrailingText, bodyAfterCommand) {
    if (inlineTrailingText.length === 0) {
        return bodyAfterCommand;
    }
    if (bodyAfterCommand.length === 0) {
        return inlineTrailingText;
    }
    return `${inlineTrailingText}\n${bodyAfterCommand}`;
}
// biome-ignore lint/complexity/noExcessiveCognitiveComplexity: Command parsing keeps token interactions explicit while side workflow options share one registry.
// biome-ignore lint/complexity/noExcessiveLinesPerFunction: Command parsing is intentionally centralized so token interactions stay explicit.
function parseWorkflowCommandTokens(tokens) {
    let workflowSelection;
    const workflowTemplateSelectors = {};
    let schedule;
    let scheduledRun;
    let firstRun;
    let recurringAutoStop;
    let baseBranch;
    const overrideEntries = [];
    const seenOverrideFlags = new Set();
    const arrayOverrideValues = new Map();
    let inlineTrailingText = "";
    let sawRecognizedOption = false;
    for (let index = 0; index < tokens.length; index += 1) {
        const applyParsedOption = (parsed, apply) => {
            const applied = (0, workflow_option_parse_shared_1.applyWorkflowCommandOptionParseResult)(parsed, index, apply);
            if (applied.kind === "invalid") {
                return applied.result;
            }
            sawRecognizedOption = true;
            index = applied.nextIndex;
            return undefined;
        };
        const token = tokens[index];
        if (token === undefined) {
            continue;
        }
        if (index === 0 && token === "pr") {
            if (seenOverrideFlags.has("issue-completion-target")) {
                return (0, workflow_option_parse_shared_1.buildInvalidWorkflowCommandOptionResult)("duplicate-option", inlineTrailingText);
            }
            seenOverrideFlags.add("issue-completion-target");
            overrideEntries.push({
                path: "issueCompletion.target",
                op: "set",
                value: "pull_request",
            });
            sawRecognizedOption = true;
            continue;
        }
        if (!token.startsWith("-")) {
            if (sawRecognizedOption) {
                inlineTrailingText = tokens.slice(index).join(" ");
                break;
            }
            return (0, workflow_option_parse_shared_1.buildInvalidWorkflowCommandOptionResult)("unexpected-argument", tokens.slice(index).join(" "));
        }
        const commandOption = workflow_command_option_specs_1.WORKFLOW_COMMAND_OPTION_BY_FLAG.get(token);
        if (commandOption?.kind === "workflow-selection") {
            const parsedWorkflowSelection = parseWorkflowSelectionOption(tokens, index, workflowSelection, inlineTrailingText);
            const invalidResult = applyParsedOption(parsedWorkflowSelection, (parsed) => {
                workflowSelection = parsed.workflowSelection;
            });
            if (invalidResult !== undefined) {
                return invalidResult;
            }
            continue;
        }
        if (commandOption?.kind === "side-workflow") {
            const parsedSideWorkflow = parseTemplateWorkflowOption(tokens, index, workflowTemplateSelectors[commandOption.surface], inlineTrailingText);
            const invalidResult = applyParsedOption(parsedSideWorkflow, (parsed) => {
                workflowTemplateSelectors[commandOption.surface] =
                    parsed.workflowTemplateSelector;
            });
            if (invalidResult !== undefined) {
                return invalidResult;
            }
            continue;
        }
        if (commandOption?.kind === "schedule") {
            const parsedSchedule = (0, workflow_schedule_option_normalizer_1.parseWorkflowScheduleOption)(tokens, index, commandOption, schedule, scheduledRun, inlineTrailingText);
            const invalidResult = applyParsedOption(parsedSchedule, (parsed) => {
                schedule = parsed.schedule;
            });
            if (invalidResult !== undefined) {
                return invalidResult;
            }
            continue;
        }
        if (commandOption?.kind === "scheduled-run") {
            const parsedScheduledRun = (0, workflow_schedule_option_normalizer_1.parseWorkflowScheduledRunOption)(tokens, index, commandOption, schedule, scheduledRun, inlineTrailingText);
            const invalidResult = applyParsedOption(parsedScheduledRun, (parsed) => {
                scheduledRun = parsed.scheduledRun;
            });
            if (invalidResult !== undefined) {
                return invalidResult;
            }
            continue;
        }
        if (commandOption?.kind === "first-run") {
            const parsedFirstRun = (0, workflow_schedule_option_normalizer_1.parseWorkflowFirstRunOption)(tokens, index, commandOption, firstRun, inlineTrailingText);
            const invalidResult = applyParsedOption(parsedFirstRun, (parsed) => {
                firstRun = parsed.firstRun;
            });
            if (invalidResult !== undefined) {
                return invalidResult;
            }
            continue;
        }
        if (commandOption?.kind === "recurring-auto-stop") {
            const parsedAutoStop = (0, workflow_recurring_auto_stop_option_normalizer_1.parseWorkflowRecurringAutoStopOption)(tokens, index, commandOption, recurringAutoStop, inlineTrailingText);
            const invalidResult = applyParsedOption(parsedAutoStop, (parsed) => {
                recurringAutoStop = parsed.recurringAutoStop;
            });
            if (invalidResult !== undefined) {
                return invalidResult;
            }
            continue;
        }
        if (commandOption?.kind === "schedule-off") {
            if (schedule !== undefined ||
                scheduledRun !== undefined ||
                firstRun !== undefined ||
                recurringAutoStop !== undefined) {
                return (0, workflow_option_parse_shared_1.buildInvalidWorkflowCommandOptionResult)("conflicting-schedule-options", inlineTrailingText);
            }
            schedule = (0, types_1.createOffWorkflowScheduleState)();
            scheduledRun = (0, types_1.createOffWorkflowScheduledRunCommand)();
            sawRecognizedOption = true;
            continue;
        }
        if (commandOption?.kind === "base-branch") {
            const parsedBaseBranch = parseBaseBranchOption(tokens, index, baseBranch, inlineTrailingText);
            const invalidResult = applyParsedOption(parsedBaseBranch, (parsed) => {
                baseBranch = parsed.baseBranch;
            });
            if (invalidResult !== undefined) {
                return invalidResult;
            }
            continue;
        }
        if (token.startsWith("--")) {
            const overrideOption = issue_override_option_registry_1.ISSUE_OVERRIDE_OPTION_REGISTRY_BY_FLAG.get(token.slice(2));
            if (overrideOption === undefined) {
                return (0, workflow_option_parse_shared_1.buildInvalidWorkflowCommandOptionResult)("unexpected-argument", tokens.slice(index).join(" "));
            }
            const parsedOverride = (0, comment_command_overrides_1.parseOverrideOption)(tokens, index, overrideOption, seenOverrideFlags, arrayOverrideValues, inlineTrailingText);
            const invalidResult = applyParsedOption(parsedOverride, (parsed) => {
                if (parsed.entry !== undefined) {
                    overrideEntries.push(parsed.entry);
                }
            });
            if (invalidResult !== undefined) {
                return invalidResult;
            }
            continue;
        }
        return (0, workflow_option_parse_shared_1.buildInvalidWorkflowCommandOptionResult)("unexpected-argument", tokens.slice(index).join(" "));
    }
    const normalizedOverridePatch = (0, comment_command_overrides_1.normalizeOverridePatchEntries)(overrideEntries, arrayOverrideValues);
    const updateFields = compactWorkflowCommandUpdateFields({
        workflowSelection,
        workflowTemplateSelectors,
        schedule,
        scheduledRun,
        firstRun,
        recurringAutoStop,
        baseBranch,
        configOverridePatch: normalizedOverridePatch.patch,
    });
    if (!hasWorkflowCommandUpdateFieldValue(updateFields)) {
        return (0, workflow_option_parse_shared_1.buildInvalidWorkflowCommandOptionResult)("missing-options", inlineTrailingText);
    }
    return {
        kind: "update",
        ...updateFields,
        inlineTrailingText,
    };
}
function parseBaseBranchOption(tokens, index, previous, inlineTrailingText) {
    if (previous !== undefined) {
        return (0, workflow_option_parse_shared_1.buildInvalidWorkflowCommandOptionResult)("duplicate-option", inlineTrailingText);
    }
    const optionValue = (0, workflow_option_parse_shared_1.parseRequiredWorkflowCommandOptionValue)(tokens, index, inlineTrailingText, (value) => (value.trim().length === 0 ? null : value));
    if (optionValue.kind === "invalid") {
        return optionValue;
    }
    return (0, workflow_option_parse_shared_1.buildWorkflowCommandOptionUpdateResult)({
        baseBranch: optionValue.parsedValue === "default"
            ? { mode: "default" }
            : { mode: "set", branch: optionValue.parsedValue },
    }, 2, inlineTrailingText);
}
function parseWorkflowSelectionOption(tokens, index, existingSelection, inlineTrailingText) {
    if (existingSelection !== undefined) {
        return (0, workflow_option_parse_shared_1.buildInvalidWorkflowCommandOptionResult)("duplicate-option", inlineTrailingText);
    }
    const optionValue = (0, workflow_option_parse_shared_1.parseRequiredWorkflowCommandOptionValue)(tokens, index, inlineTrailingText, parseWorkflowTemplateSelectorValue);
    if (optionValue.kind === "invalid") {
        return optionValue;
    }
    return (0, workflow_option_parse_shared_1.buildWorkflowCommandOptionUpdateResult)({ workflowSelection: optionValue.parsedValue }, 2, inlineTrailingText);
}
function parseTemplateWorkflowOption(tokens, index, existingWorkflowName, inlineTrailingText) {
    if (existingWorkflowName !== undefined) {
        return (0, workflow_option_parse_shared_1.buildInvalidWorkflowCommandOptionResult)("duplicate-option", inlineTrailingText);
    }
    const optionValue = (0, workflow_option_parse_shared_1.parseRequiredWorkflowCommandOptionValue)(tokens, index, inlineTrailingText, parseWorkflowTemplateSelectorValue);
    if (optionValue.kind === "invalid") {
        return optionValue;
    }
    return (0, workflow_option_parse_shared_1.buildWorkflowCommandOptionUpdateResult)({ workflowTemplateSelector: optionValue.parsedValue }, 2, inlineTrailingText);
}
function parseWorkflowTemplateSelectorValue(value) {
    if (value === types_1.WORKFLOW_TEMPLATE_AUTO_SENTINEL) {
        return { mode: "auto" };
    }
    if (value === types_1.WORKFLOW_TEMPLATE_AUTO_SELECT_SENTINEL) {
        return { mode: "auto_select" };
    }
    if (value === types_1.WORKFLOW_TEMPLATE_NO_TEMPLATE_SENTINEL) {
        return { mode: "no_template" };
    }
    const normalizedSelector = (0, types_1.normalizeWorkflowTemplatePath)(value);
    if (normalizedSelector === null) {
        return null;
    }
    return { mode: "template", templatePath: normalizedSelector };
}
