"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.warn = exports.wait = exports.url = exports.tree = exports.trace = exports.Table = exports.table = exports.styledObject = exports.styledJSON = exports.styledHeader = exports.prompt = exports.progress = exports.prideAction = exports.log = exports.info = exports.flush = exports.ExitError = exports.exit = exports.error = exports.done = exports.debug = exports.confirm = exports.Config = exports.config = exports.anykey = exports.annotation = exports.ActionBase = exports.action = exports.ux = void 0;
const Errors = require("../errors");
const util = require("util");
const chalk = require("chalk");
const base_1 = require("./action/base");
Object.defineProperty(exports, "ActionBase", { enumerable: true, get: function () { return base_1.ActionBase; } });
const config_1 = require("./config");
Object.defineProperty(exports, "config", { enumerable: true, get: function () { return config_1.config; } });
Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return config_1.Config; } });
const exit_1 = require("./exit");
Object.defineProperty(exports, "ExitError", { enumerable: true, get: function () { return exit_1.ExitError; } });
const styled = require("./styled");
const styled_1 = require("./styled");
Object.defineProperty(exports, "Table", { enumerable: true, get: function () { return styled_1.Table; } });
const uxPrompt = require("./prompt");
const wait_1 = require("./wait");
const stream_1 = require("./stream");
const hyperlinker = require('hyperlinker');
function timeout(p, ms) {
    function wait(ms, unref = false) {
        return new Promise(resolve => {
            const t = setTimeout(() => resolve(null), ms);
            if (unref)
                t.unref();
        });
    }
    return Promise.race([p, wait(ms, true).then(() => Errors.error('timed out'))]);
}
async function _flush() {
    const p = new Promise(resolve => {
        stream_1.stdout.once('drain', () => resolve(null));
    });
    const flushed = stream_1.stdout.write('');
    if (flushed) {
        return Promise.resolve();
    }
    return p;
}
class ux {
    static get prompt() {
        return uxPrompt.prompt;
    }
    /**
     * "press anykey to continue"
     */
    static get anykey() {
        return uxPrompt.anykey;
    }
    static get confirm() {
        return uxPrompt.confirm;
    }
    static get action() {
        return config_1.config.action;
    }
    static get prideAction() {
        return config_1.config.prideAction;
    }
    // eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types
    static styledObject(obj, keys) {
        this.info(styled.styledObject(obj, keys));
    }
    static styledHeader(header) {
        this.info(chalk.dim('=== ') + chalk.bold(header) + '\n');
    }
    static get styledJSON() {
        return styled.styledJSON;
    }
    static get table() {
        return styled.Table.table;
    }
    static get tree() {
        return styled.tree;
    }
    static get wait() {
        return wait_1.default;
    }
    static get progress() {
        return styled.progress;
    }
    static async done() {
        config_1.config.action.stop();
    }
    static trace(format, ...args) {
        if (this.config.outputLevel === 'trace') {
            stream_1.stdout.write(util.format(format, ...args) + '\n');
        }
    }
    static debug(format, ...args) {
        if (['trace', 'debug'].includes(this.config.outputLevel)) {
            stream_1.stdout.write(util.format(format, ...args) + '\n');
        }
    }
    static info(format, ...args) {
        stream_1.stdout.write(util.format(format, ...args) + '\n');
    }
    static log(format, ...args) {
        this.info(format || '', ...args);
    }
    static url(text, uri, params = {}) {
        const supports = require('supports-hyperlinks');
        if (supports.stdout) {
            this.log(hyperlinker(text, uri, params));
        }
        else {
            this.log(uri);
        }
    }
    static annotation(text, annotation) {
        const supports = require('supports-hyperlinks');
        if (supports.stdout) {
            // \u001b]8;;https://google.com\u0007sometext\u001b]8;;\u0007
            this.log(`\u001B]1337;AddAnnotation=${text.length}|${annotation}\u0007${text}`);
        }
        else {
            this.log(text);
        }
    }
    static async flush(ms = 10000) {
        await timeout(_flush(), ms);
    }
}
exports.ux = ux;
ux.config = config_1.config;
const action = ux.action;
exports.action = action;
const annotation = ux.annotation;
exports.annotation = annotation;
const anykey = ux.anykey;
exports.anykey = anykey;
const confirm = ux.confirm;
exports.confirm = confirm;
const debug = ux.debug;
exports.debug = debug;
const done = ux.done;
exports.done = done;
const error = Errors.error;
exports.error = error;
const exit = Errors.exit;
exports.exit = exit;
const flush = ux.flush;
exports.flush = flush;
const info = ux.info;
exports.info = info;
const log = ux.log;
exports.log = log;
const prideAction = ux.prideAction;
exports.prideAction = prideAction;
const progress = ux.progress;
exports.progress = progress;
const prompt = ux.prompt;
exports.prompt = prompt;
const styledHeader = ux.styledHeader;
exports.styledHeader = styledHeader;
const styledJSON = ux.styledJSON;
exports.styledJSON = styledJSON;
const styledObject = ux.styledObject;
exports.styledObject = styledObject;
const table = ux.table;
exports.table = table;
const trace = ux.trace;
exports.trace = trace;
const tree = ux.tree;
exports.tree = tree;
const url = ux.url;
exports.url = url;
const wait = ux.wait;
exports.wait = wait;
const warn = Errors.warn;
exports.warn = warn;
const cliuxProcessExitHandler = async () => {
    try {
        await ux.done();
    }
    catch (error) {
        console.error(error);
        process.exitCode = 1;
    }
};
// to avoid MaxListenersExceededWarning
// only attach named listener once
const cliuxListener = process.listeners('exit').find(fn => fn.name === cliuxProcessExitHandler.name);
if (!cliuxListener) {
    process.once('exit', cliuxProcessExitHandler);
}
