"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.resolveInitValues = resolveInitValues;
exports.resolveInitConfigExtends = resolveInitConfigExtends;
exports.resolveRepositoryHostRemoteName = resolveRepositoryHostRemoteName;
const control_plane_config_1 = require("../../config/control-plane-config");
const numbers_1 = require("../../core/numbers");
const fs_errors_1 = require("../../core/fs-errors");
const structured_clone_1 = require("../../core/structured-clone");
const native_git_repository_client_1 = require("../../git/native-git-repository-client");
const remote_name_1 = require("../../git/remote-name");
const catalog_1 = require("../../i18n/catalog");
const display_time_1 = require("../../i18n/display-time");
const prompts_1 = require("../prompts");
const locale_1 = require("./locale");
async function resolveInitValues(cwd, options, input = {}) {
    const baseDefaults = await loadInitDefaults(cwd);
    const locale = await (0, locale_1.resolveInitLocale)(cwd, options);
    const prompter = input.prompter ?? (0, prompts_1.createCliPrompter)({ locale });
    const configExtends = await resolveInitConfigExtends(options, prompter, locale);
    const defaults = (0, control_plane_config_1.applyConfigExtendsPreset)(baseDefaults, configExtends);
    const i18n = resolveInitI18nValues(options, defaults, locale);
    const repositoryHost = await resolveRepositoryHostInitValues(cwd, options, baseDefaults, prompter);
    const ticketTracker = await resolveTicketTrackerInitValues(baseDefaults.ticketTracker);
    const pollIntervalSec = Number(options.pollIntervalSec ?? defaults.pollIntervalSec);
    (0, numbers_1.parsePositiveInteger)((0, catalog_1.translate)(locale, "init.command.validate.pollInterval"), String(pollIntervalSec), locale);
    const parallelism = resolveInitParallelismValues(options, defaults.parallelism, locale);
    const aiRunLimitsMaxRuns = Number(options.aiRunLimitsMaxRuns ?? defaults.aiRunLimits.maxRuns);
    (0, numbers_1.parseNonNegativeInteger)((0, catalog_1.translate)(locale, "init.command.validate.aiRunLimitsMaxRuns"), String(aiRunLimitsMaxRuns), locale);
    const aiRunLimitsMaxHours = Object.hasOwn(options, "aiRunLimitsMaxHours")
        ? (options.aiRunLimitsMaxHours ?? null)
        : defaults.aiRunLimits.maxHours;
    const defaultPullRequest = baseDefaults.repositoryHost.pullRequest ??
        control_plane_config_1.DEFAULT_CONFIG.repositoryHost.pullRequest;
    const reviewersInput = options.reviewers?.join(",") ??
        (await prompter.input({
            label: (0, catalog_1.translate)(locale, "init.command.prompt.defaultReviewers"),
            defaultValue: defaultPullRequest.defaultReviewers.join(","),
            validate: () => { },
        }));
    const defaultReviewers = reviewersInput
        .split(",")
        .map((value) => value.trim())
        .filter((value) => value.length > 0);
    const pullRequest = repositoryHost.pullRequest ??
        baseDefaults.repositoryHost.pullRequest ??
        control_plane_config_1.DEFAULT_CONFIG.repositoryHost.pullRequest;
    return {
        ...defaults,
        i18n,
        repositoryHost: {
            ...repositoryHost,
            pullRequest: {
                ...pullRequest,
                defaultReviewers,
            },
        },
        ticketTracker,
        workers: input.workers ?? baseDefaults.workers,
        pollIntervalSec,
        parallelism,
        aiRunLimits: {
            maxRuns: aiRunLimitsMaxRuns,
            maxHours: aiRunLimitsMaxHours,
        },
    };
}
async function resolveInitConfigExtends(options, prompter, locale) {
    return (options.configExtends ??
        (await prompter.select({
            label: (0, catalog_1.translate)(locale, "init.command.prompt.configExtends"),
            options: [
                {
                    value: "balanced",
                    label: (0, catalog_1.translate)(locale, "init.command.prompt.configExtends.balanced"),
                },
                {
                    value: "aggressive",
                    label: (0, catalog_1.translate)(locale, "init.command.prompt.configExtends.aggressive"),
                },
                {
                    value: "conservative",
                    label: (0, catalog_1.translate)(locale, "init.command.prompt.configExtends.conservative"),
                },
            ],
            defaultValue: "balanced",
        })));
}
function resolveInitI18nValues(options, defaults, locale) {
    const defaultLanguage = options.language ?? defaults.i18n.defaultLanguage;
    if (!(0, catalog_1.isAppLocale)(defaultLanguage)) {
        throw new Error((0, catalog_1.translate)(locale, "cli.parser.init.invalidLanguage", {
            value: String(defaultLanguage),
        }));
    }
    const displayTimeZone = options.displayTimeZone ?? defaults.i18n.displayTimeZone;
    if (!(0, display_time_1.isSupportedTimeZone)(displayTimeZone)) {
        throw new Error((0, catalog_1.translate)(locale, "config.error.displayTimeZoneInvalid"));
    }
    return {
        defaultLanguage,
        displayTimeZone,
    };
}
function resolveInitParallelismValues(options, defaults, locale) {
    const maxWorkers = Number(options.maxWorkers ?? defaults.maxWorkers);
    (0, numbers_1.parsePositiveInteger)((0, catalog_1.translate)(locale, "init.command.validate.maxWorkers"), String(maxWorkers), locale);
    const maxIssues = Number(options.maxIssues ?? defaults.maxIssues);
    (0, numbers_1.parsePositiveInteger)((0, catalog_1.translate)(locale, "init.command.validate.maxIssues"), String(maxIssues), locale);
    validateInitParallelism(maxWorkers, maxIssues, locale);
    const mode = options.parallelismMode ?? defaults.mode;
    return { maxWorkers, maxIssues, mode };
}
function validateInitParallelism(maxWorkers, maxIssues, locale) {
    if (maxIssues <= maxWorkers) {
        return;
    }
    throw new Error((0, catalog_1.translate)(locale, "init.command.validate.parallelism"));
}
async function resolveRepositoryHostInitValues(cwd, options, defaults, prompter) {
    const locale = await (0, locale_1.resolveInitLocale)(cwd, options);
    const remoteName = await resolveRepositoryHostRemoteName(cwd, options, prompter);
    const repositoryHostDefaults = defaults.repositoryHost;
    const pullRequestDefaults = repositoryHostDefaults.pullRequest ??
        control_plane_config_1.DEFAULT_CONFIG.repositoryHost.pullRequest;
    const baseBranch = options.repositoryHostBaseBranch ??
        (await prompter.input({
            label: (0, catalog_1.translate)(locale, "init.command.prompt.repositoryBaseBranch"),
            defaultValue: (await (0, native_git_repository_client_1.discoverGitRemoteDefaultBranch)(cwd, remoteName)) ??
                defaults.repositoryHost.baseBranch,
            validate: (value) => validateNonEmpty(locale, (0, catalog_1.translate)(locale, "init.command.validate.repositoryBaseBranch"), value),
        }));
    return {
        remoteName,
        baseBranch,
        pullRequest: {
            defaultReviewers: [...pullRequestDefaults.defaultReviewers],
        },
    };
}
function resolveTicketTrackerInitValues(defaults) {
    const ticketTrackerDefaults = defaults;
    return {
        commentReactions: [...ticketTrackerDefaults.commentReactions],
        showStepProgressInTitles: ticketTrackerDefaults.showStepProgressInTitles,
        workflowLabels: { ...ticketTrackerDefaults.workflowLabels },
    };
}
async function loadInitDefaults(cwd) {
    try {
        return (await (0, control_plane_config_1.loadConfigWithExtends)(cwd)).config;
    }
    catch (error) {
        if (!(0, fs_errors_1.isMissingFileError)(error)) {
            throw error;
        }
        return discoverDefaults();
    }
}
function discoverDefaults() {
    const defaultsInput = (0, structured_clone_1.cloneStructured)(control_plane_config_1.DEFAULT_CONFIG);
    delete defaultsInput.workflowTemplateDefaults?.followup;
    return control_plane_config_1.controlPlaneConfigSchema.parse(defaultsInput);
}
async function resolveRepositoryHostRemoteName(cwd, options, prompter) {
    const locale = await (0, locale_1.resolveInitLocale)(cwd, options);
    const label = (0, catalog_1.translate)(locale, "init.command.prompt.repositoryRemoteName");
    const remoteName = options.repositoryHostRemoteName ??
        (await resolveDiscoveredRemoteName(cwd, prompter, locale, label));
    validateRemoteName(locale, label, remoteName);
    return remoteName;
}
async function resolveDiscoveredRemoteName(cwd, prompter, locale, label) {
    const remoteNames = await (0, native_git_repository_client_1.discoverGitRemoteNames)(cwd);
    if (remoteNames.length === 1) {
        return remoteNames[0] ?? control_plane_config_1.DEFAULT_CONFIG.repositoryHost.remoteName;
    }
    if (remoteNames.length > 1) {
        if (!prompter.interactive) {
            throw new Error("Multiple git remotes found. Pass --remote-name <name>.");
        }
        return prompter.select({
            label,
            options: remoteNames.map((remoteName) => ({
                value: remoteName,
                label: remoteName,
            })),
            defaultValue: remoteNames.includes(control_plane_config_1.DEFAULT_CONFIG.repositoryHost.remoteName)
                ? control_plane_config_1.DEFAULT_CONFIG.repositoryHost.remoteName
                : (remoteNames[0] ?? control_plane_config_1.DEFAULT_CONFIG.repositoryHost.remoteName),
        });
    }
    return prompter.input({
        label,
        defaultValue: control_plane_config_1.DEFAULT_CONFIG.repositoryHost.remoteName,
        validate: (value) => validateRemoteName(locale, label, value),
    });
}
function validateNonEmpty(locale, label, value) {
    if (value.trim().length === 0) {
        throw new Error((0, catalog_1.translate)(locale, "init.command.validate.notEmpty", { label }));
    }
}
function validateRemoteName(locale, label, value) {
    validateNonEmpty(locale, label, value);
    if (!(0, remote_name_1.isValidRemoteName)(value)) {
        throw new Error((0, catalog_1.translate)(locale, "init.command.validate.invalidIdentifier", { label }));
    }
}
