<?PHP
/**
 * Provides an interface for CLI outputs of museum-digital's dev and admin tools.
 *
 * @author Joshua Ramon Enslin <joshua@museum-digital.de>
 */

/**
 * Interface for CLI outputs of museum-digital's dev and admin tools.
 */
class MDConsole {

    const CONSOLE_STATUS_NOTICE = 0;
    const CONSOLE_STATUS_UPDATE = 1;
    const CONSOLE_STATUS_DELETION = 2;
    const CONSOLE_STATUS_ERROR = 3;
    const CONSOLE_STATUS_SKIPPED = 3;

    const CONSOLE_LEVEL_COLORS = [
        self::CONSOLE_STATUS_NOTICE   => "",
        self::CONSOLE_STATUS_ERROR    => "41", // 0: Red background   | Problem
        self::CONSOLE_STATUS_UPDATE   => "42", // 1: Green background | Edited automatically
        self::CONSOLE_STATUS_DELETION => "44", // 2: Blue background | Deleted
        self::CONSOLE_STATUS_SKIPPED  => "40", // 2: Blue background | Deleted
    ];

    const CONSOLE_LOG_USED_RESOURCES_ENABLED = 1;
    const CONSOLE_LOG_USED_RESOURCES_DISABLED = 0;

    /**
     * Prints a headline.
     *
     * @param string  $msg   Message to print.
     * @param integer $level Heading level.
     *
     * @return void
     */
    final public static function heading(string $msg, int $level = 2):void {

        if ($level < 1 || $level > 6) {
            throw new MDConsoleInvalidHeadingNumber("Invalid heading number");
        }

        $msgLen = strlen($msg);
        echo sprintf("      \033[1;30;m\033[0m\033[1m%s \033[0m" . PHP_EOL, $msg);

        if ($level >= 3) return;

        switch ($level) {
        case 1:
            $headingLvlChar = "=";
        case 2:
        default:
            $headingLvlChar = "-";
        }

        for ($i = 0; $i < $msgLen + 6; $i++) echo $headingLvlChar;
        echo PHP_EOL;

    }

    /**
     * Prints a headline.
     *
     * @param string $msg Message to print.
     *
     * @return void
     */
    final public static function note(string $msg):void {

        echo PHP_EOL . sprintf("\033[30m(%s)%s \033[0m" . PHP_EOL . PHP_EOL, date("H:i:s"), $msg);

    }

    /**
     * Formats a message uniformly, maybe also to stdout.
     *
     * @param string  $context        Context this is called from.
     * @param integer $level          Level of the notification.
     * @param integer $editedNo       Number of edited entries.
     * @param string  $additionalNote Optional, additional note.
     * @param string  $link           Link.
     *
     * @return void
     */
    final public static function write(string $context, int $level = self::CONSOLE_STATUS_NOTICE, int $editedNo = 0, string $additionalNote = "", string $link = ""):void {

        // Get parts for generating the message to log.
        $additionalNote = strtr($additionalNote, ["Γ€" => "ae", "ΓΆ" => "oe", "ΓΌ" => "ue"]);
        $date = date("H:i:s");    // Get current date & time.

        // Generate the message to log.
        # $message = sprintf("%1$07s", memory_get_usage()) . " :: {$date} :: {$msg}" . PHP_EOL;

        $levelColor = self::CONSOLE_LEVEL_COLORS[$level];

        if (empty($link))
            echo sprintf("\033[1;30;" . $levelColor . "m_____\033[0m\033[0m %-20s \033[40m::\033[0m # \033[32m%+9s\033[0m \033[40m::\033[0m πŸ“ %-50s \033[40m::\033[0m πŸ“… %+20s\n", $context, $editedNo, $additionalNote, $date);
        else
            echo sprintf("\033[1;30;" . $levelColor . "m_____\033[0m\033[0m %-20s \033[40m::\033[0m # \033[32m%+9s\033[0m \033[40m::\033[0m πŸ“ %-50s \033[40m::\033[0m πŸ“… %+20s \033[40m::\033[0m $link\n", $context, $editedNo, $additionalNote, $date);;

    }

    /**
     * Sets up last line of CLI output.
     *
     * @return void
     */
    final public static function setupCLI():void {

        $startTime = microtime(true);
        register_shutdown_function(function($startTime) {

            $duration = microtime(true) - $startTime;

            if ($duration < 30) return;

            toNote("Long script run", round($duration, 2), "Script run time, that's: ");
            toNote("Long script run", memory_get_peak_usage(), "Peak memory usage");
            toNote("Long script run", memory_get_usage(), "Memory usage at end of script");

            # print_r($GLOBALS);
        }, $startTime);

    }

    /**
     * Constructor.
     *
     * @return void
     */
    public function __construct() {

        self::setupCLI();

    }

}