<?php
namespace apexl\Io;
use apexl\Config\Singleton;
use apexl\Io\includes\System;
use Whoops\Handler\JsonResponseHandler;
use Whoops\Run;


class Client{
    public static $instance;
    protected $configDir;
    protected $configFile;

    /** @var System */
    protected $system;

    private function __construct(){
        $whoops = new Run();
        $whoops->pushHandler(new JsonResponseHandler());
        $whoops->register();
    }

    /**
     * Turn Io into a singleton.
     * @return Client
     */
    public static function getInstance(){
        if(!self::$instance){
            self::$instance = new Client();
        }
        return self::$instance;
    }

    /**
     * Set the primary configuration Dir for IO
     * @param $dir
     * @return $this
     */
    public function setConfigDir($dir){
        $this->configDir = realpath(rtrim($dir, DIRECTORY_SEPARATOR));
        //check if we have a config cacheDir - if not, create a default one.
        $cacheDir = Singleton::getCacheDirectory();
        if($cacheDir){
            $this->setConfigCacheDir($cacheDir);
        }
        return $this;
    }

    /**
     * Set the directory used to store the amalgamated config files / data as cache.
     * @param $dir
     * @return $this
     */
    public function setConfigCacheDir($dir){
        Singleton::setCacheDirectory($dir);
        return $this;
    }

    /**
     * Set the application base path
     * @param $basePath
     */
    public function setBasePath($basePath){
        System::setBasePath($basePath);
    }

    /**
     * Bootstrap IO CMF
     */
    private function bootstrap(){
        $this->coreConfigPath = $this->configDir.DIRECTORY_SEPARATOR.ltrim($this->configFile, DIRECTORY_SEPARATOR);
        Singleton::load($this->coreConfigPath);

        // Attempt Initialise the System
        $this->system = System::getInstance();

        //run pre-load operations

        //Load modules etc.

        //run post-load operations

        //Cleanup
    }

    /**
     * Bootstrap and run Io
     */
    public function start($configFile){
        $this->configFile = $configFile;
        $this->bootstrap();

        //Run Slim Framework
        $this->system->start();
    }
}