"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.buildIssueBroadcastArgs = buildIssueBroadcastArgs;
exports.buildIssueBroadcastTarget = buildIssueBroadcastTarget;
exports.assignIssueBroadcastMessage = assignIssueBroadcastMessage;
exports.assignIssueBroadcastSelector = assignIssueBroadcastSelector;
exports.parseIssueBroadcastStatus = parseIssueBroadcastStatus;
exports.parseIssueIds = parseIssueIds;
exports.parseSingleIssueId = parseSingleIssueId;
exports.requireOptionValue = requireOptionValue;
exports.parseRequiredOptionValue = parseRequiredOptionValue;
exports.requireParsedOption = requireParsedOption;
exports.parseIssueState = parseIssueState;
exports.parseIssueView = parseIssueView;
exports.parseIssueFormat = parseIssueFormat;
exports.parsePositiveIntegerArg = parsePositiveIntegerArg;
exports.parseNonNegativeIntegerArg = parseNonNegativeIntegerArg;
exports.parseNonNegativeNumberArg = parseNonNegativeNumberArg;
exports.parseNonEmptyStringArg = parseNonEmptyStringArg;
exports.parseNonEmptyFreeformTextArg = parseNonEmptyFreeformTextArg;
const catalog_1 = require("../../i18n/catalog");
const types_1 = require("../../issues/types");
const constants_1 = require("../../platform/constants");
const types_2 = require("../../platform/workflow-state/types");
const ISSUE_BROADCAST_STATUSES = [
    types_2.WORKFLOW_STATUSES.aiReady,
    types_2.WORKFLOW_STATUSES.aiRunning,
    types_2.WORKFLOW_STATUSES.aiNeedsHuman,
    types_2.WORKFLOW_STATUSES.aiWorkingInPr,
    types_2.WORKFLOW_STATUSES.aiRecurring,
    types_2.WORKFLOW_STATUSES.aiScheduled,
    types_2.WORKFLOW_RULES.aiDisabled,
];
const DEFAULT_ISSUE_BROADCAST_STATUSES = [
    types_2.WORKFLOW_STATUSES.aiReady,
    types_2.WORKFLOW_STATUSES.aiRunning,
    types_2.WORKFLOW_STATUSES.aiNeedsHuman,
];
function buildIssueBroadcastArgs(state, locale) {
    if (state.message === undefined) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.issue.broadcast.messageError"));
    }
    if (state.selectorKind === undefined) {
        if (state.statuses.length > 0 || state.labels.length > 0) {
            throw new Error((0, catalog_1.translate)(locale, "cli.parser.issue.broadcast.openFilterError"));
        }
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.issue.broadcast.selectorError"));
    }
    const args = {
        message: state.message,
        target: buildIssueBroadcastTarget(state, locale),
    };
    if (state.dryRun) {
        args.dryRun = true;
    }
    return args;
}
function buildIssueBroadcastTarget(state, locale) {
    switch (state.selectorKind) {
        case "issue":
            if (state.statuses.length > 0 || state.labels.length > 0) {
                throw new Error((0, catalog_1.translate)(locale, "cli.parser.issue.broadcast.openFilterError"));
            }
            return {
                kind: "issue",
                issueIds: state.issueIds,
            };
        case "open":
            return {
                kind: "open",
                statuses: state.statuses.length > 0
                    ? dedupeIssueBroadcastStatuses(state.statuses)
                    : [...DEFAULT_ISSUE_BROADCAST_STATUSES],
                labels: state.labels,
            };
        default:
            throw new Error((0, catalog_1.translate)(locale, "cli.parser.issue.broadcast.selectorError"));
    }
}
function assignIssueBroadcastMessage(state, message, locale) {
    if (state.message !== undefined) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.issue.broadcast.messageError"));
    }
    state.message = message;
}
function assignIssueBroadcastSelector(state, selectorKind, locale) {
    if (state.selectorKind !== undefined && state.selectorKind !== selectorKind) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.issue.broadcast.selectorError"));
    }
    state.selectorKind = selectorKind;
}
function parseIssueBroadcastStatus(value, locale) {
    if (ISSUE_BROADCAST_STATUSES.includes(value)) {
        return value;
    }
    throw new Error((0, catalog_1.translate)(locale, "cli.parser.invalidStatusValue", { value }));
}
function dedupeIssueBroadcastStatuses(statuses) {
    return [...new Set(statuses)];
}
function parseIssueIds(token, value, locale) {
    return requireOptionValue(token, value, locale)
        .split(",")
        .map((entry) => entry.trim())
        .filter((entry) => entry.length > 0)
        .map((rawValue) => parseTrackerItemId(rawValue, locale));
}
function parseSingleIssueId(token, value, locale) {
    const issueIds = parseIssueIds(token, value, locale);
    if (issueIds.length !== 1) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.exactlyOneIssueNumber", { token }));
    }
    const [issueId] = issueIds;
    if (!issueId) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.exactlyOneIssueNumber", { token }));
    }
    return issueId;
}
function parseTrackerItemId(value, locale) {
    const mergeRequestMatch = /^mr:(\d+)$/iu.exec(value);
    if (mergeRequestMatch) {
        const [, rawNumber = ""] = mergeRequestMatch;
        return `mr:${parsePositiveIntegerArg((0, catalog_1.translate)(locale, "cli.parser.issueNumber"), rawNumber, locale)}`;
    }
    return String(parsePositiveIntegerArg((0, catalog_1.translate)(locale, "cli.parser.issueNumber"), value, locale));
}
function requireOptionValue(token, value, locale) {
    if (value === undefined) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.missingValue", { token }));
    }
    return value;
}
function parseRequiredOptionValue(token, value, locale, parse) {
    return parse(requireOptionValue(token, value, locale));
}
function requireParsedOption(value, option, locale) {
    if (value === undefined) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.missingRequiredOption", { option }));
    }
    return value;
}
function parseIssueState(value, locale) {
    if (value === constants_1.PLATFORM_ISSUE_LIST_STATES.open ||
        value === constants_1.PLATFORM_ISSUE_LIST_STATES.closed ||
        value === constants_1.PLATFORM_ISSUE_LIST_STATES.all) {
        return value;
    }
    throw new Error((0, catalog_1.translate)(locale, "cli.parser.invalidStateValue", { value }));
}
function parseIssueView(value, locale) {
    if (value === "compact" || value === "detailed") {
        return value;
    }
    throw new Error((0, catalog_1.translate)(locale, "cli.parser.invalidViewValue", { value }));
}
function parseIssueFormat(value, locale) {
    if (value === types_1.ISSUE_REPORT_FORMATS.text ||
        value === types_1.ISSUE_REPORT_FORMATS.markdown) {
        return value;
    }
    throw new Error((0, catalog_1.translate)(locale, "cli.parser.invalidFormatValue", { value }));
}
function parsePositiveIntegerArg(label, value, locale) {
    const parsed = Number(value);
    if (!Number.isInteger(parsed) || parsed <= 0) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.positiveInteger", { label, value }));
    }
    return parsed;
}
function parseNonNegativeIntegerArg(label, value, locale) {
    const parsed = Number(value);
    if (value.trim().length === 0 || !Number.isInteger(parsed) || parsed < 0) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.nonNegativeInteger", { label, value }));
    }
    return parsed;
}
function parseNonNegativeNumberArg(label, value, locale) {
    const parsed = Number(value);
    if (value.trim().length === 0 || !Number.isFinite(parsed) || parsed < 0) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.nonNegativeNumber", { label, value }));
    }
    return parsed;
}
function parseNonEmptyStringArg(token, value, locale) {
    if (value.trim().length === 0) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.emptyValue", { token }));
    }
    return value;
}
function parseNonEmptyFreeformTextArg(token, value, locale) {
    const decoded = decodeCliFreeformTextEscapes(value);
    if (decoded.trim().length === 0) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.emptyValue", { token }));
    }
    return decoded;
}
function decodeCliFreeformTextEscapes(value) {
    let decoded = "";
    for (let index = 0; index < value.length; index += 1) {
        const char = value[index];
        if (char !== "\\") {
            decoded += char;
            continue;
        }
        const next = value[index + 1];
        if (next === undefined) {
            decoded += char;
            continue;
        }
        switch (next) {
            case "n":
                decoded += "\n";
                index += 1;
                break;
            case "r":
                decoded += "\r";
                index += 1;
                break;
            case "\\":
                decoded += "\\";
                index += 1;
                break;
            default:
                decoded += char;
        }
    }
    return decoded.replace(/\r\n?/g, "\n");
}
