<?php

namespace MGModule\DNSManager2\mgLibs\process;
use MGModule\DNSManager2 as main;
use MGModule\DNSManager2\mgLibs;
use function ModulesGarden\Servers\ZimbraEmail\Core\Helper\getAdminDirName;
use ModulesGarden\Servers\ZimbraEmail\Core\ModuleConstants;

/**
 * Main Abstract Controller 
 * 
 * @author Michal Czech <michael@modulesgarden.com>
 */
abstract class abstractMainDriver{
    /**
     * Single Ton Instance
     * 
     * @var mainController
     */
    static private $_instance;
    
    /**
     * This Var define Debug Mode in Module
     * 
     * @var boolean
     */
    public $_debug = false;
    
    /**
     * Mark 
     * 
     * $var boolean
     */
    public $isLoaded;
        
    /**
     * Load Configuration
     * 
     * @var configuration
     */
    private $_configuration;
    
    /**
     * Is Loaded From Admin Area
     * 
     * @var boolean 
     */
    private $_isAdmin = false;

    /**
     * Key For Data Encryption
     * 
     * @var string 
     */
    private $encryptSecureKey;
    
    /**
     * Main Namespace
     * 
     * @var string
     */
    private $_mainNamespace;
    
    private $_mainDIR;
    
    /**
     * Disable Contruct && Clone
     */
    private final function __construct() {;}
    private final function __clone() {;}
    
    public $page = 'home';
    
    /**
     * Get SingleTon Instance
     * 
     * @return mainController
     */
    public static function I($force = false, $configs = array()){
        if(empty(self::$_instance) || $force)
        {
            $class = get_called_class();
            
            mainInstance::setInstanceName($class);
                        
            self::$_instance = new $class();
            self::$_instance->_mainNamespace = substr(__NAMESPACE__,0,  strpos(__NAMESPACE__, '\mgLibs'));
            self::$_instance->_mainDIR = call_user_func(array($class,'getMainDIR'));

            $class= self::$_instance->_mainNamespace.'\configuration';
            
            self::$_instance->_configuration = new $class();
            
            foreach($configs as $name => $value)
            {
                self::$_instance->_configuration->{$name} = $value;
            }
            
            self::$_instance->isLoaded = true;
            
            if(!empty(self::$_instance->_configuration->debug))
            {
                self::$_instance->_debug = true;
            }
                    
            main\mgLibs\MySQL\query::useCurrentConnection();
            main\mgLibs\lang::getInstance(self::$_instance->_mainDIR.DS.'langs');
        }
        
        return self::$_instance;
    }    
    
    function configuration(){
        return $this->_configuration;
    }
    
    public function isAdmin($status = null){
        if($status !== null)
        {
            $this->_isAdmin = $status;
        }
        return $this->_isAdmin;
    }
    
    public function isDebug(){
        return $this->_debug;
    }

    /**
     * Return Main Namespace
     * 
     * @return string
     */
    function getMainNamespace(){
        return $this->_mainNamespace;
    }
    
    /**
     * Return Enrypt Key
     * 
     * @return string
     */
    public function getEncryptKey(){
        
        if(empty($this->encryptSecureKey))
        {
            $this->encryptSecureKey = hash('sha256', $GLOBALS['cc_encryption_hash'].$this->configuration()->encryptHash,TRUE);
        }
        
        return $this->encryptSecureKey;
    }
        
    function setMainLangContext(){
        mgLibs\lang::setContext($this->getType().($this->isAdmin()?'AA':'CA'));
    }
    
    /**
     * Process Controllers
     * 
     * @param string $controller controller name
     * @param array $input input array
     * @param string $type type of request
     * @return array
     * @throws main\mgLibs\exceptions\system
     * @throws main\mgLibs\exceptions\system
     */
    function runControler($controller,$action = 'index',$input = array(), $type = 'HTML'){
        $this->page = $controller;

        try{
            $className = $this->getMainNamespace()."\\controllers\\".$this->getType()."\\".($this->_isAdmin?'admin':'clientarea')."\\".$controller;

            try
            {
                if(!class_exists($className))
                {
                    throw new main\mgLibs\exceptions\system("Unable to find page");
                }
            }
            catch (\Exception $exception)
            {
                if(!self::I()->isAdmin())
                {
                    header('Location: index.php?m=DNSManager2');
                    die;
                }
                throw $exception;
            }


            $controllerOBJ = new $className($input);
            
            if(!method_exists($controllerOBJ, $action.$type))
            {
                if(!self::I()->isAdmin())
                {
                    header('Location: index.php?m=DNSManager2');
                    die;
                }

                throw new main\mgLibs\exceptions\system("Unable to find Action: ".$action.$type);
            }

            main\mgLibs\lang::stagCurrentContext('generate'.$controller);
                       
            main\mgLibs\lang::addToContext($controller);

            main\mgLibs\smarty::I()->setTemplateDir(self::I()->getModuleTemplatesDir().DS.'pages'.DS.$controller);

            $result = $controllerOBJ->{$action.$type}($input);

            switch ($type)
            {
                case 'HTML':
                    if(empty($result['tpl']))
                    {
                        throw new main\mgLibs\exceptions\system("Provide Template Name");
                    }
                    
                    $success = isset($result['vars']['success'])?$result['vars']['success']:false;
                    $error = isset($result['vars']['error'])?$result['vars']['error']:false;
                    $result = main\mgLibs\smarty::I()->view($result['tpl'], $result['vars']);
                break;
                default:
                    $success = isset($result['success'])?$result['success']:false;
                    $error = isset($result['error'])?$result['error']:false;
            }

            main\mgLibs\lang::unstagContext('generate'.$controller);

            return array(
                $result
                ,$success
                ,$error
            );
        } catch (\Exception $ex) {

            main\mgLibs\lang::unstagContext('generate'.$controller);

            $query = array_merge($_GET, $_POST);
            \logModuleCall(
                'DNS Manager', __METHOD__, $ex->getMessage(), var_export($ex, true), var_export($query, true)
            );

            main\mgLibs\custom\manager\LogHelper::addFailLog('Load Page', $ex->getMessage(), "Render Page Action. Check module logs to see more");

            header('Location: index.php?m=DNSManager2');
            die;
        }
    }

    /**
     * @return bool
     */
    public static function isAdminArea()
    {
        if (isset($_SESSION['adminid']) && isset($_SERVER['REQUEST_URI']) && strpos($_SERVER['REQUEST_URI'], '/' . static::getAdminDirName() . '/') !== false)
        {
            return true;
        }

        return false;
    }

    /**
     * @return string
     */
    public static function getAdminDirName()
    {
        $fileName = 'configuration.php';
        $filePath = dirname(dirname(dirname(dirname(dirname(__DIR__)))));

        global $customadminpath;
        if (!$customadminpath && file_exists($filePath . DIRECTORY_SEPARATOR . $fileName))
        {
            include_once $filePath . DIRECTORY_SEPARATOR . $fileName;
        }

        if ($customadminpath && is_string($customadminpath))
        {
            return $customadminpath;
        }

        return 'admin';
    }

    /**
     * Dump data
     * 
     * @param mixed $input
     */
    static function dump($input)
    {
        if(self::I()->isDebug())
        {
            echo "<pre>";
            print_r($input);
            echo "</pre>";
        }
    }
    
    abstract public function getAssetsURL();
    abstract public function getType();
    
    public static function getMainDIR(){
        return false;
    }
    public static function getUrl(){
        return false;
    }
}