<?php
/**
 * @copyright NetMonsters <team@netmonsters.ru>
 * @link http://netmonsters.ru
 * @package Majestic
 * @subpackage util
 * @since 2010-03-09
 * @version SVN: $Id$
 * @filesource $URL$
 */

class Profiler
{

    protected $start = null;

    protected $end = null;

    protected $queries = array();

    static protected $instance = null;

    private function __construct()
    {
        if (DEBUG == false) {
            throw new GeneralException('Need to turn on DEBUG before use.');
        }
    }

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

    /**
     * @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->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/>'
                . '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();
        }
        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
                . 'Queries: ' . count($this->queries) . ' [' . round($queriesTime * 1000, 2) . ' ms] ' . PHP_EOL;
        $html .= $temp;
        return $html;
    }
}