"use strict";
/*
 * @poppinss/cliui
 *
 * (c) Harminder Virk <virk@adonisjs.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.MinimalRenderer = void 0;
const Icons_1 = require("../../Icons");
const Logger_1 = require("../../Logger");
const Console_1 = require("../../Renderer/Console");
/**
 * As the name suggests, render tasks in minimal UI for better viewing
 * experience.
 */
class MinimalRenderer {
    constructor(options, testing = false) {
        this.options = options;
        this.testing = testing;
    }
    /**
     * Returns the renderer for rendering the messages
     */
    getRenderer() {
        if (!this.renderer) {
            this.renderer = new Console_1.ConsoleRenderer();
        }
        return this.renderer;
    }
    /**
     * Instantiates the logger and defines a custom renderer
     * to log messages in context with the currently running
     * task
     */
    instantiateLogger() {
        /**
         * The minimal renderer must always be used when term
         * has support for colors and is tty
         */
        this.logger = new Logger_1.Logger({ ...this.options, dim: true }, this.testing);
        this.logger.useRenderer({
            log: (message) => this.renderTasks(message),
            logError: (message) => this.renderTasks(message),
            logUpdate: (message) => this.renderTasks(message),
            logUpdateDone: () => { },
        });
    }
    /**
     * Returns the presentation string for an idle task
     */
    presentIdleTask(task) {
        return `${this.logger.colors.dim(Icons_1.icons.pointer)} ${this.logger.colors.dim(task.title)}`;
    }
    /**
     * Returns the presentation string for a running task. The log line is
     * updated when logger recieves the message.
     */
    presentRunningTask(task, logLine) {
        let message = `${Icons_1.icons.pointer} ${task.title}`;
        if (!logLine) {
            return message;
        }
        const lines = logLine.trim().split('\n');
        return `${message}\n  ${lines[0]}`;
    }
    /**
     * Returns the presentation string for a failed task
     */
    presentFailedTask(task) {
        const pointer = this.logger.colors.red(Icons_1.icons.pointer);
        const duration = this.logger.colors.dim(task.duration);
        let message = `${pointer} ${task.title} ${duration}`;
        if (!task.completionMessage) {
            return message;
        }
        const errorMessage = typeof task.completionMessage === 'string'
            ? task.completionMessage
            : task.completionMessage.message;
        message = `${message}\n  ${this.logger.colors.red(errorMessage)}`;
        return message;
    }
    /**
     * Returns the presentation string for a succeeded task
     */
    presentSucceededTask(task) {
        const pointer = this.logger.colors.green(Icons_1.icons.pointer);
        const duration = this.logger.colors.dim(task.duration);
        let message = `${pointer} ${task.title} ${duration}`;
        if (!task.completionMessage) {
            return message;
        }
        message = `${message}\n  ${this.logger.colors.dim(task.completionMessage)}`;
        return message;
    }
    /**
     * Renders a given task
     */
    renderTask(task, logLine) {
        switch (task.state) {
            case 'idle':
                return this.presentIdleTask(task);
            case 'running':
                return this.presentRunningTask(task, logLine);
            case 'succeeded':
                return this.presentSucceededTask(task);
            case 'failed':
                return this.presentFailedTask(task);
        }
    }
    /**
     * Re-renders all tasks by inspecting their current state
     */
    renderTasks(logLine) {
        this.getRenderer().logUpdate(this.registeredTasks.map((task) => this.renderTask(task, logLine)).join('\n'));
    }
    /**
     * Define a custom renderer. Logs to "stdout" and "stderr"
     * by default
     */
    useRenderer(renderer) {
        this.renderer = renderer;
        return this;
    }
    /**
     * Register tasks to render
     */
    tasks(tasks) {
        this.registeredTasks = tasks;
        return this;
    }
    /**
     * Render all tasks
     */
    render() {
        this.instantiateLogger();
        this.registeredTasks.forEach((task) => task.onUpdate(() => this.renderTasks()));
        this.renderTasks();
    }
}
exports.MinimalRenderer = MinimalRenderer;
