<?php

namespace SmartData;

require_once( __DIR__ . '/Config.php');

abstract class Logger
{
	public static $IDENT = 'SmartData';
    private static $TO_FILE = false;
    private static $LEVEL = LOG_DEBUG;
    public static $TO_SCREEN = false;

    private static $_buffer = null;

	// LOG_ERR
    // LOG_NOTICE
    // LOG_INFO
    // LOG_DEBUG

    public static function time_elapsed($reset=false)
    {
        static $last = null;
        $now = microtime(true)*1000000;
        if ($last != null && !$reset) {
            Logger::debug('<!-- ' . ($now - $last) . ' us -->', true);
        }
        $last = $now;
    }

	public static function debug(string $message, bool $force=false) {
        self::_log($message, LOG_DEBUG, $force);
    }

    public static function debug_X(string $message, $ctrl=false) {
        if(is_string($ctrl))
            $message = "{$ctrl}> {$message}";
        self::_log($message, LOG_DEBUG, ( ($ctrl === true || Config::config()::HYSTERICALLY_DEBUGGED || (Config::config()::DEBUGGED[$ctrl] ?? false) ) ));
    }

	public static function exception(\Exception $e) {
		$message = get_class($e) . "> {$e->getFile()}:{$e->getLine()}> {$e->getMessage()}\n";
        $message .= $e->getTraceAsString()."\n";

        self::_log($message, LOG_ERR, true);
    }

    public static function print_r($object, bool $force=false) {
        ob_start();
        print_r($object);
        $log = ob_get_clean();
        self::debug($log, $force);
    }

    public static function var_dump($object, bool $force=false) {
        ob_start();
        var_dump($object);
        $log = ob_get_clean();
        self::debug($log, $force);
    }

    public static function flush() {
        if(Config::config()::BUFFERED_LOG && Logger::$_buffer != null){
            self::_write(Logger::$_buffer);
        }
        Logger::$_buffer = null;
    }

    private static function _log(string $message, int $priority, bool $force=false) {
        global $__FORCE_SCREEN_LOG;
        $log = date("Y-m-d h:i:s").' '.$message;

        $flag = (filesize(Config::config()::LOG_FILE) > (10 * 1024 * 1024)) ? 0 : FILE_APPEND;
        if (Logger::$TO_SCREEN || Logger::$TO_FILE || $force){
            if(Config::config()::BUFFERED_LOG && !isset($__FORCE_SCREEN_LOG) && $priority !== LOG_ERR){
                Logger::$_buffer = (Logger::$_buffer ?? '') . $log . "\n";
            } else {
                self::_write($log);
            }
        }

    }

    private static function _write(string $message) {
        global $__FORCE_SCREEN_LOG;
        if (Logger::$TO_SCREEN || (isset($__FORCE_SCREEN_LOG) && $__FORCE_SCREEN_LOG === true) ){
            echo $message."\n";
        } else {
            $flag = (filesize(Config::config()::LOG_FILE) > (200 * 1024 * 1024)) ? 0 : FILE_APPEND;
            file_put_contents(Config::config()::LOG_FILE, $message."\n", $flag);
        }
    }
}

openlog(Logger::$IDENT, LOG_PID | LOG_PERROR, LOG_LOCAL0);