"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.AwaitDeploymentCompletion = void 0;
const awaitCompletion_1 = require("../../commandUtil/awaitCompletion");
const executionResultPresenter_1 = require("./executionResultPresenter");
const loggingProvider_1 = require("@mablhq-internal/runtime/providers/logging/loggingProvider");
const timeUtil_1 = require("@mablhq-internal/runtime/util/timeUtil");
const chalk = require('chalk');
class AwaitDeploymentCompletion extends awaitCompletion_1.AwaitCompletion {
    constructor(apiClient, exitOnFirstFailure, isSilent) {
        super(apiClient, AwaitDeploymentCompletion.pollingTimeoutMilliseconds, AwaitDeploymentCompletion.pollingIntervalMilliseconds);
        this.apiClient = apiClient;
        this.resultsPresenter = new executionResultPresenter_1.ExecutionResultPresenter();
        this.exitOnFirstFailure = !!exitOnFirstFailure;
        this.isSilent = !!isSilent;
    }
    async pollingFunction(mablApi, lastEntity, seedId) {
        if (!seedId) {
            throw new Error('event id must be passed');
        }
        const latestResults = await mablApi.getDeploymentResults(seedId);
        if (this.exitOnFirstFailure) {
            if (latestResults.plan_execution_metrics?.failed ?? 0 > 0) {
                this.exitOnFirstFailurePresenter(latestResults);
                return {
                    newEntity: latestResults,
                    status: awaitCompletion_1.PollingOutcomeType.Complete,
                };
            }
        }
        const hasOutcomePayload = latestResults?.event_status &&
            Object.keys(latestResults?.event_status).length > 0;
        const status = hasOutcomePayload
            ? awaitCompletion_1.PollingOutcomeType.Complete
            : awaitCompletion_1.PollingOutcomeType.Running;
        return {
            newEntity: latestResults,
            status,
        };
    }
    statusPresenter(lastEntity) {
        if (this.isSilent) {
            return;
        }
        const elapsedTimeString = (0, timeUtil_1.elapsedTimeDurationToString)(this.getElapsedMilliseconds());
        const passed = lastEntity.plan_execution_metrics?.passed ?? 0;
        const failed = lastEntity.plan_execution_metrics?.failed ?? 0;
        const total = lastEntity.plan_execution_metrics?.total ?? 0;
        const passedColor = passed === 0 ? 'gray' : 'green';
        const failedColor = failed === 0 ? 'gray' : 'red';
        let totalColor = 'gray';
        if (failed > 0) {
            totalColor = 'red';
        }
        else if (passed > 0) {
            totalColor = 'green';
        }
        loggingProvider_1.logger.info(`Plan Runs [passed: ${chalk
            .keyword(passedColor)
            .visible(passed.toString())}, failed: ${chalk
            .keyword(failedColor)
            .visible(failed.toString())}, total: ${chalk
            .keyword(totalColor)
            .visible(total.toString())}] elapsed ${elapsedTimeString}`);
    }
    completedStatusPresenter(lastEntity) {
        if (this.isSilent) {
            return;
        }
        let color = 'yellow';
        let statusString = 'UNKNOWN';
        if (lastEntity.event_status) {
            const isSuccess = lastEntity.event_status.succeeded;
            color = isSuccess ? 'green' : 'red';
            statusString = isSuccess ? 'SUCCESS' : 'FAILED';
        }
        loggingProvider_1.logger.info(chalk.bold('\nTests complete with status  ') +
            chalk.keyword(color).bold(statusString) +
            '\n');
        loggingProvider_1.logger.info(this.resultsPresenter.entityToString(lastEntity));
    }
    exitOnFirstFailurePresenter(lastEntity) {
        if (this.isSilent) {
            return;
        }
        loggingProvider_1.logger.info(chalk.bold('\nAt least one Plan Run has ') +
            chalk.bold.red('FAILED') +
            chalk.bold('. Failing fast and exiting.'));
        loggingProvider_1.logger.info(chalk.bold('Additional tests may still be running. Check the mabl app for details. '));
        loggingProvider_1.logger.info(this.resultsPresenter.entityToString(lastEntity));
    }
    timeoutStatusPresenter() {
        loggingProvider_1.logger.info(chalk.yellow.bold('CLI timed out awaiting test completion.'));
    }
}
exports.AwaitDeploymentCompletion = AwaitDeploymentCompletion;
AwaitDeploymentCompletion.pollingTimeoutMilliseconds = 6 * 60 * 60 * 1000;
AwaitDeploymentCompletion.pollingIntervalMilliseconds = 10 * 1000;
