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 { prettyPrintEnvironmentPrompt } from "../utils/pretty-print-environment-prompt.js";
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 {
        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());
            if (environmentJsonFromDeveloperAPI.data.length === 0) {
                await printCriticalFailureToConsoleAndExit("Error: You don't have any preview or production environments for this project to link against. First, deploy this project using zuplo deploy and then link against that.");
            }
            const environments = environmentJsonFromDeveloperAPI.data
                .map((env) => {
                return {
                    [prettyPrintEnvironmentPrompt(env, false)]: env.name,
                };
            })
                .reduce((acc, curr) => {
                return { ...acc, ...curr };
            });
            try {
                argv.environment = await select({
                    message: "Select the environment",
                    choices: Object.entries(environments)
                        .map(([key, value]) => {
                        return {
                            name: key,
                            value: value,
                        };
                    })
                        .sort((a, b) => a.name.localeCompare(b.name)),
                });
            }
            catch (error) {
                if (error.isTtyError || error.name === "ExitPromptError") {
                    process.exit(0);
                }
                logger.trace("Failed to select account", 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 && branchRef.all && 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