<?php namespace Majestic\Util\Profiler;
/**
 * @copyright NetMonsters <team@netmonsters.ru>
 * @link http://netmonsters.ru
 * @package Majestic
 * @subpackage util
 * @since 2010-03-09
 */

class Profiler
{

    /**
     * @var int
     */
    protected $start = null;

    /**
     * @var int
     */
    protected $end = null;

    /**
     * @var CommandProfiler[]
     */
    protected $queries = array();

    static protected $instance = null;

    private function __construct()
    {
        if (\Majestic\Config::get('PROFILER') == false) {
            throw new GeneralException('Need turn PROFILER before use.');
        }
    }

    /**
     * Refuse cloning
     * @codeCoverageIgnoreStart
     */
    private function __clone()
    {
    }

    /**
     * @codeCoverageIgnoreEnd
     */

    /**
     * @return Profiler
     */
    static public function getInstance()
    {
        if (!isset(self::$instance)) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * @param string $type
     * @param string $command
     * @return CommandProfiler
     */
    public function profilerCommand($type, $command)
    {
        $profiler = new CommandProfiler($type, $command);
        $this->queries[] = $profiler;
        return $profiler;
    }

    public function start()
    {
        $this->queries = array();
        $this->start = microtime(true);
    }

    public function end($html)
    {
        $this->end = microtime(true);
        if (stripos($html, '</body>') == False) {
            return $html;
        }
        return str_ireplace('</body>', $this->getOutput() . '</body>', $html);
    }

    protected function getOutput()
    {
        $temp = '';
        $queriesTime = 0;
        foreach ($this->queries as $query) {
            $temp .= '(' . $query->getType() . ') [' . round($query->getElapsed() * 1000, 2) . 'ms] ' . $query->getCommand() . '<br/>';
            $queriesTime += $query->getElapsed();
        }
        $html = '<div style="clear:both; font:12px monospace; margin: 5px; white-space: pre;">'
                . 'Elapsed time: ' . round(($this->end - $this->start) * 1000, 2) . 'ms.<br/>';
        if (count($this->queries) == 0 && !Config::get('PROFILER_DETAILS')) {
            $html .= 'Queries not counted. Turn PROFILER_DETAILS if you want to profile queries.<br/>';
        } else {
            $html .= 'Queries: ' . count($this->queries) . ' [' . round($queriesTime * 1000, 2) . ' ms]<br/>';
        }
        $html .= $temp;
        $html .= '</div>';
        return $html;
    }

    public function getJson()
    {
        $this->end = microtime(true);
        FB::info(round(($this->end - $this->start) * 1000, 2) . ' ms', 'Elapsed time');
        $table = array();
        $table[] = array('Type', 'Time (ms)', 'Query');

        $queriesTime = 0;
        foreach ($this->queries as $query) {
            $table[] = array($query->getType(), round($query->getElapsed() * 1000, 2), $query->getCommand());
            $queriesTime += $query->getElapsed();
        }
        if (count($this->queries) == 0 && !Config::get('PROFILER_DETAILS')) {
            FB::table('Queries not counted. Turn PROFILER_DETAILS if you want to profile queries.', $table);
        } else {
            FB::table('Queries: ' . count($this->queries) . ' [' . round($queriesTime * 1000, 2) . ' ms]', $table);
        }
    }

    public function getCli()
    {
        $this->end = microtime(true);
        $queriesTime = 0;
        $temp = str_pad(PHP_EOL, 60, '-', STR_PAD_LEFT);
        foreach ($this->queries as $query) {
            $temp .= sprintf('%-25s[% 10sms]  %s', '(' . $query->getType() .')', round($query->getElapsed() * 1000, 2), $query->getCommand()) . PHP_EOL;
            $queriesTime += $query->getElapsed();
        }
        $html  = str_pad(PHP_EOL, 60, '-', STR_PAD_LEFT);
        $html .= 'Elapsed time: ' . round(($this->end - $this->start) * 1000, 2) . 'ms.' . PHP_EOL;
        if (count($this->queries) == 0 && !Config::get('PROFILER_DETAILS')) {
            $html .= 'Queries not counted. Turn PROFILER_DETAILS if you want to profile queries.' . PHP_EOL;
        } else {
            $html .= 'Queries: ' . count($this->queries) . ' [' . round($queriesTime * 1000, 2) . ' ms] ' . PHP_EOL;
        }
        $html .= $temp;
        return $html;
    }
}