<?php namespace Majestic\App;
/**
 * @copyright NetMonsters <team@netmonsters.ru>
 * @link http://netmonsters.ru
 * @package Majestic
 * @subpackage App
 * @since 27.06.12
 *
 */

/**
 * @desc CliController (run cli_class, end profiler)
 * @author Aleksandr Demidov
 */
class CliController
{
    /**
     * @var CliController
     */
    protected static $instance;

    protected $error_stream;

    protected function __construct()
    {
        //\Majestic\Exception\ErrorHandler::init();
        $this->error_stream = \Majestic\Config::get('ErrorStream', 'php://stderr');
    }

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

    /**
     * @codeCoverageIgnoreEnd
     */

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

    /**
     * @param iCli|string $cli
     * @throws \ErrorException|\Majestic\Exception\GeneralException
     */
    public function execute($cli)
    {
        try {
            $this->run($cli);
        }
        catch (\Exception $e) {
            $this->exception($e);
        }
    }

    protected function run($cli)
    {
        if (is_string($cli)) {
            if (!class_exists($cli)) {
                throw new \Majestic\Exception\GeneralException('Action class "' . $cli . '" not found.');
            }
            $cli = new $cli;
        }
        if (!in_array('Majestic\App\iCli', class_implements($cli))) {
            throw new \ErrorException('Runner "' . get_class($cli) . '" need implement of "iCli" interface.');
        }
        $cli->run();
        if (\Majestic\Config::get('PROFILER')) {
            $profile = \Majestic\Util\Profiler\Profiler::getInstance()->getCli();
            if (\Majestic\Config::get('LOGGING')) {
	            \Majestic\Logger\Logger::getInstance()->log($profile);
            } else {
                echo $profile;
            }
        }
    }

    protected function exception($e)
    {
        $code = $e->getCode();
        if ($e instanceof \ErrorException) {
            $code = $e->getSeverity();
        }
        file_put_contents($this->error_stream, PHP_EOL . 'Error ' . '#' . $code . ': ' . $e->getMessage() . PHP_EOL, FILE_APPEND);
        file_put_contents($this->error_stream, PHP_EOL . 'Stack trace: ' . PHP_EOL . $e->getTraceAsString() . PHP_EOL, FILE_APPEND);
    }
}