import { logger } from "../common/logger.js";
import { printCriticalFailureToConsoleAndExit, textOrJson, } from "../common/output.js";
import settings from "../common/settings.js";
function wait(duration = settings.POLL_INTERVAL) {
    return new Promise((resolve) => setTimeout(resolve, duration));
}
export async function pollDeployment(argv, fileId, account, project, spinner) {
    const MAX_RETRY_ATTEMPTS_FOR_SERVER_UPDATES = 5;
    let CURRENT_RETRY_ATTEMPTS_FOR_SERVER_UPDATES = 0;
    for (let pollRetry = 0; pollRetry < settings.MAX_POLL_RETRIES; pollRetry++) {
        spinner.suffixText = `(${pollRetry}/${settings.MAX_POLL_RETRIES})`;
        const response = await fetch(`${settings.ZUPLO_DEVELOPER_API_ENDPOINT}/v1/accounts/${account}/projects/${project}/deployment-status/${fileId}`, {
            method: "GET",
            headers: {
                Authorization: `Bearer ${argv.authToken}`,
            },
        });
        if (response.ok) {
            const rawJSON = await response.text();
            const { status, url, logUrl } = JSON.parse(rawJSON);
            switch (status) {
                case "IN_PROGRESS":
                    await wait();
                    continue;
                case "SUCCESS": {
                    logger.debug(`Checking if API is live: ${url}`);
                    const parsedUrl = new URL(url);
                    if (parsedUrl.hostname.includes(".zuplo.app")) {
                        try {
                            const zupResponse = await fetch(`${parsedUrl.origin}/__zuplo/build`);
                            if (zupResponse.ok) {
                                return {
                                    url,
                                    logUrl,
                                };
                            }
                            else {
                                logger.debug({ status: zupResponse.status }, "Error while polling deployment");
                                try {
                                    const result = await zupResponse.text();
                                    logger.debug(result);
                                }
                                catch {
                                }
                                await wait();
                                continue;
                            }
                        }
                        catch (error) {
                            logger.debug("Error while polling for zuplo build", error);
                            await wait();
                            continue;
                        }
                    }
                    else {
                        return {
                            url,
                            logUrl,
                        };
                    }
                }
                case "ERROR":
                    return {
                        logUrl,
                    };
            }
        }
        else if (response.status === 404) {
            await wait();
            continue;
        }
        else if (response.status === 500 &&
            CURRENT_RETRY_ATTEMPTS_FOR_SERVER_UPDATES <
                MAX_RETRY_ATTEMPTS_FOR_SERVER_UPDATES) {
            CURRENT_RETRY_ATTEMPTS_FOR_SERVER_UPDATES++;
            await wait();
            continue;
        }
        else {
            logger.error(`Unexpected error from server while polling for deployment: ${response.status} ${response.statusText} ${textOrJson(await response.text())}`);
            throw new Error(`Unexpected response from server while polling for deployment: ${response.status} ${response.statusText}`);
        }
    }
    return {
        logUrl: "https://portal.zuplo.com",
    };
}
export async function pollBuild(argv, endpoint, buildName, spinner) {
    const MAX_RETRY_ATTEMPTS_FOR_SERVER_UPDATES = 5;
    let CURRENT_RETRY_ATTEMPTS_FOR_SERVER_UPDATES = 0;
    for (let pollRetry = 0; pollRetry < settings.MAX_POLL_RETRIES; pollRetry++) {
        spinner.suffixText = `(${pollRetry}/${settings.MAX_POLL_RETRIES})`;
        const response = await fetch(`${endpoint}/v1/deployments/build/${buildName}`, {
            method: "GET",
            headers: {
                Authorization: `Bearer ${argv.authToken}`,
            },
        });
        if (response.ok) {
            const { conditionType, status, reason, message } = await response.json();
            switch (conditionType) {
                case "Complete":
                case "Failed":
                    return {
                        conditionType,
                        status,
                        reason,
                        message,
                    };
                default:
                    await wait();
                    continue;
            }
        }
        else if (response.status === 404) {
            await wait();
            continue;
        }
        else if (response.status === 500 &&
            CURRENT_RETRY_ATTEMPTS_FOR_SERVER_UPDATES <
                MAX_RETRY_ATTEMPTS_FOR_SERVER_UPDATES) {
            CURRENT_RETRY_ATTEMPTS_FOR_SERVER_UPDATES++;
            await wait();
            continue;
        }
        else {
            logger.error(JSON.stringify(await response.json(), null, 2), "Failed to upload to self-hosted build endpoint");
            await printCriticalFailureToConsoleAndExit("Error: Failed to upload to self-hosted build endpoint");
        }
    }
    return {};
}
//# sourceMappingURL=poll-deployment.js.map