import { select } from "@inquirer/prompts";
import { simpleGit } from "simple-git";
import { logger } from "../logger.js";
import { printCriticalFailureToConsoleAndExit, textOrJson } from "../output.js";
import settings from "../settings.js";
import { isInteractiveTerminal } from "../terminal.js";
import { buildEnvironmentPromptChoices } from "../utils/build-environment-prompt-choices.js";
export const ENVIRONMENT_EXPLICIT_KEY = "environmentExplicit";
export const FETCHED_ENVIRONMENTS_KEY = "fetchedEnvironments";
export function recordEnvironmentExplicit(argv) {
    argv[ENVIRONMENT_EXPLICIT_KEY] = hasEnvironmentFlag(process.argv);
}
export function hasEnvironmentFlag(args) {
    for (let i = 2; i < args.length; i++) {
        const arg = args[i];
        if (arg === "--environment" || arg.startsWith("--environment=")) {
            return true;
        }
    }
    return false;
}
export async function fetchEnvironment(argv) {
    if (argv.environment && typeof argv.environment === "string") {
        return;
    }
    if (!argv.account || typeof argv.account !== "string") {
        throw new Error("Invalid state: account is not set.");
    }
    if (!argv.project || typeof argv.project !== "string") {
        throw new Error("Invalid state: project is not set.");
    }
    const branch = await getGitBranch(argv);
    if (branch && !argv["fetch-environments"]) {
        argv.environment = branch;
    }
    else {
        if (!isInteractiveTerminal()) {
            await printCriticalFailureToConsoleAndExit("Error: --environment is required in non-interactive environments (e.g. CI/CD).\nUse the --environment flag to specify an environment name.");
            return;
        }
        const baseUrl = `${settings.ZUPLO_DEVELOPER_API_ENDPOINT}/v1/environments`;
        const queryParams = {
            accountName: argv.account,
            projectName: argv.project,
        };
        const url = new URL(baseUrl);
        url.search = new URLSearchParams(queryParams).toString();
        const response = await fetch(url, {
            method: "GET",
            headers: {
                Authorization: `Bearer ${argv.authToken}`,
            },
        });
        if (response.ok) {
            const environmentJsonFromDeveloperAPI = (await response.json());
            const deploymentsUrl = new URL(`${settings.ZUPLO_DEVELOPER_API_ENDPOINT}/v1/accounts/${argv.account}/projects/${argv.project}/deployments`);
            const deploymentsResponse = await fetch(deploymentsUrl, {
                method: "GET",
                headers: {
                    Authorization: `Bearer ${argv.authToken}`,
                },
            });
            if (deploymentsResponse.ok) {
                const { data: deployments } = (await deploymentsResponse.json());
                const workingCopies = deployments
                    .filter((d) => d.environmentType === "WORKING_COPY")
                    .map((d) => ({
                    name: d.name,
                    accountName: d.accountName,
                    projectName: d.projectName,
                    branchName: d.branchName,
                    environmentType: "working_copy",
                    createdOn: new Date(d.createdOn),
                }));
                environmentJsonFromDeveloperAPI.data.push(...workingCopies);
            }
            else {
                logger.debug({
                    status: deploymentsResponse.status,
                    statusText: deploymentsResponse.statusText,
                }, "Failed to fetch working-copy deployments for project");
            }
            if (environmentJsonFromDeveloperAPI.data.length === 0) {
                await printCriticalFailureToConsoleAndExit("Error: You don't have any environments for this project to link against. First, deploy this project using zuplo deploy and then link against that.");
            }
            argv[FETCHED_ENVIRONMENTS_KEY] = environmentJsonFromDeveloperAPI.data;
            try {
                argv.environment = await select({
                    message: "Select the environment",
                    choices: buildEnvironmentPromptChoices(environmentJsonFromDeveloperAPI.data),
                });
            }
            catch (error) {
                if (error.isTtyError || error.name === "ExitPromptError") {
                    process.exit(1);
                }
                logger.trace("Failed to select environment", error);
                process.exit(1);
            }
        }
        else {
            logger.trace({
                status: response.status,
                statusText: response.statusText,
                response: textOrJson(await response.text()),
            }, "Failed to request environments for project");
            await printCriticalFailureToConsoleAndExit("Error: Failed to request environments for the project.");
        }
    }
}
async function getGitBranch(argv) {
    let branch;
    const dir = argv.dir;
    if (dir && typeof dir === "string") {
        const git = simpleGit({ baseDir: dir });
        const isGitRepo = await git.checkIsRepo();
        if (isGitRepo) {
            const status = await git.status();
            if (!status.current) {
                throw new Error("Invalid state: Directory is in detached head state.");
            }
            branch = status.current.trim();
            if (branch === "HEAD") {
                await git.fetch(["--all"]);
                const branchCommit = await git.branch(["-a"]);
                const branchRef = await git.branch([
                    "-r",
                    "--contains",
                    branchCommit.current,
                ]);
                if (branchRef?.all?.[0]) {
                    const originBranch = branchRef.all[0];
                    const cleanOriginBranch = originBranch.replace(/^origin\//, "");
                    if (!cleanOriginBranch) {
                        throw new Error("Invalid state: Directory is in detached head state.");
                    }
                    branch = cleanOriginBranch.trim();
                }
            }
        }
    }
    return branch;
}
//# sourceMappingURL=get-environment-param.js.map