"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const core_1 = require("@oclif/core");
const chalk_1 = __importDefault(require("chalk"));
const ora_1 = __importDefault(require("ora"));
const cli_app_service_1 = require("../../lib/services/cli-app.service");
const resolve_cluster_1 = require("../../lib/resolve-cluster");
const TERMINAL = new Set([
    'COMPLETED',
    'FAILED',
    'CANCELLED',
]);
class AppBuild extends core_1.Command {
    async run() {
        const { args, flags } = await this.parse(AppBuild);
        const spinner = (0, ora_1.default)(`Fetching latest build for "${args.name}"...`).start();
        try {
            const { id: clusterId } = await (0, resolve_cluster_1.resolveCluster)(flags.cluster);
            const service = await cli_app_service_1.CliAppService.create(clusterId);
            const app = await service.getAppByName(args.name);
            let build = await service.getLatestBuild(app.id);
            if (!build) {
                spinner.stop();
                console.log(chalk_1.default.yellow(`\n  No builds found for ${app.name}.\n`));
                return;
            }
            if (flags.refresh) {
                spinner.text = 'Refreshing from provider...';
                build = await service.refreshBuild(build.id);
            }
            if (!flags.watch) {
                spinner.stop();
                if (flags.output === 'json') {
                    console.log(JSON.stringify(build, null, 2));
                }
                else {
                    this.printBuild(app.name, build);
                }
                return;
            }
            // Watch mode
            while (!TERMINAL.has(build.status)) {
                spinner.text = `Build ${build.status.toLowerCase()}... (${new Date().toLocaleTimeString()})`;
                await sleep(flags.interval * 1000);
                try {
                    build = await service.refreshBuild(build.id);
                }
                catch {
                    // Fallback to plain GET if refresh fails transiently
                    build = await service.getBuild(build.id);
                }
            }
            spinner.stop();
            if (flags.output === 'json') {
                console.log(JSON.stringify(build, null, 2));
            }
            else {
                this.printBuild(app.name, build);
            }
            if (build.status !== 'COMPLETED')
                this.exit(1);
        }
        catch (error) {
            spinner.fail('Failed to fetch build');
            console.log(chalk_1.default.red(`\n  Error: ${error.message}\n`));
            this.exit(1);
        }
    }
    printBuild(appName, b) {
        console.log(chalk_1.default.cyan(`\n  Latest build — ${appName}\n`));
        console.log(`  ${chalk_1.default.bold('ID:')}        ${b.id}`);
        console.log(`  ${chalk_1.default.bold('Status:')}    ${colorStatus(b.status)}`);
        console.log(`  ${chalk_1.default.bold('Provider:')}  ${b.provider}`);
        console.log(`  ${chalk_1.default.bold('Branch:')}    ${b.branch}`);
        if (b.commitSha)
            console.log(`  ${chalk_1.default.bold('Commit:')}    ${b.commitSha.slice(0, 12)}`);
        if (b.imageRef)
            console.log(`  ${chalk_1.default.bold('Image:')}     ${b.imageRef}`);
        if (b.externalUrl)
            console.log(`  ${chalk_1.default.bold('Run URL:')}   ${chalk_1.default.dim(b.externalUrl)}`);
        if (b.errorMessage)
            console.log(`  ${chalk_1.default.bold('Error:')}     ${chalk_1.default.red(b.errorMessage)}`);
        console.log('');
    }
}
AppBuild.description = 'Inspect or refresh the latest build for an application. ' +
    'Use --watch to follow the status until terminal.';
AppBuild.examples = [
    '<%= config.bin %> <%= command.id %> my-api',
    '<%= config.bin %> <%= command.id %> my-api --watch',
    '<%= config.bin %> <%= command.id %> my-api --refresh',
];
AppBuild.args = {
    name: core_1.Args.string({
        description: 'Application name or slug',
        required: true,
    }),
};
AppBuild.flags = {
    cluster: core_1.Flags.string({ char: 'c' }),
    output: core_1.Flags.string({
        char: 'o',
        options: ['text', 'json'],
        default: 'text',
    }),
    refresh: core_1.Flags.boolean({
        description: 'Force the backend to re-poll GitHub Actions for the latest build now',
    }),
    watch: core_1.Flags.boolean({
        char: 'w',
        description: 'Poll until the latest build reaches a terminal status (COMPLETED / FAILED / CANCELLED)',
    }),
    interval: core_1.Flags.integer({
        description: 'Polling interval in seconds (with --watch)',
        default: 5,
    }),
};
exports.default = AppBuild;
function colorStatus(s) {
    if (s === 'COMPLETED')
        return chalk_1.default.green(s);
    if (s === 'FAILED' || s === 'CANCELLED')
        return chalk_1.default.red(s);
    if (s === 'PENDING')
        return chalk_1.default.dim(s);
    return chalk_1.default.blue(s);
}
function sleep(ms) {
    return new Promise((r) => setTimeout(r, ms));
}
