<?php
/**
 * Route class is used to load dynamically the controlers from each module
 */
class Route
{   private static $user;
    private static $apiVersion;

    function __construct($user, $version){
        spl_autoload_register(function ($className) {
            self::autoloadClass($className);
        });
        self::$user = $user;
        self::$apiVersion = $version;
    }

    /**
    *@param String $module the name of the modules
    *@param String $controller the name of the contorle can be api, page or nothing
    *@param String $action the name of the method to be executed from module controller
    */
    public static function call($module, $controller, $action, $apiScriptKey = ''){
        if ($controller === 'page') {
            $action = 'showPage';
        }

        $controllerClassName =  $module.'Controller';
        $controller = new $controllerClassName();

        if ($module !== 'login' && $module !== 'translate' && $module !== 'terms' && !self::$user->isLoggedIn() && !self::isAPiKeyValid($apiScriptKey)){
            $userInfo = self::$user->getUserInfo();
            $message = isset($userInfo) && isset($userInfo['errorMessage']) ? $userInfo['errorMessage'] : '';
            trigger_error("You need to login in order to access this module! $message", E_USER_ERROR);
        }

        if (!method_exists ($controller, $action)){
            trigger_error("Module $action method not found for $controllerClassName!", E_USER_ERROR);
        }

        if(!self::hasRightsForModule($module) && !self::isAPiKeyValid($apiScriptKey) && $module !== 'terms'){
            trigger_error("This module is not available!", E_USER_ERROR);
        }

        if($action !== 'checkActivityStatus'){
            self::$user->setLastActivity();
        }

        $controller->{ $action }();
    }

    /**
     * [loadClass description]
     * @param  String $fileName name of the full path to the file
     * @return Boolean returns true if file is foound
     */
    private static function loadClass($fileName){
        if ( file_exists($fileName) ){
            require_once($fileName);
            return true;
        } else {
            return false;
        }
    }

    /**
     *@param $className String name of the class to be autoloaded
     */
    private static function autoloadClass($className){
        $isClassLoaded = false;
        $apiPath = ROOT_DIR . PATH_COMPONENTS . self::$apiVersion .'/';
        $classFolders = scandir($apiPath);

        foreach ($classFolders as $folder) {
            if (!in_array($folder, array(".",".."))){
                $fileName = $apiPath . $folder . '/' . ucfirst($className) .'.php';
                $isClassLoaded = self::loadClass($fileName);
                if ($isClassLoaded){
                    break;
                }
            }
        }

        if(!$isClassLoaded){
            $fileName = ROOT_DIR . PATH_CORE . ucfirst($className) .'.php';
            if (!self::loadClass($fileName)){
                trigger_error("Module $fileName not found!", E_USER_ERROR);
            }
        }
    }

    /**
     * get all avaialable modules for user
     * @return Array modules array
     */
    public static function getModules(){
        global $database;

        $idUserType = self::$user->getIdUserType();
        $whereSql = self::$apiVersion === 'v1' ? "AND m.isInMenu=1" : "AND m.idParent IS NULL";

        $sql = "SELECT
                    m.id,
                    m.name,
                    m.menuName,
                    m.url,
                    m.isInMenu
                FROM ".TABLES['modules']." m
                INNER JOIN ".TABLES['rel_user_types_modules']." um
                ON m.id=um.idModule
                WHERE
                    um.idUserType=".$idUserType."
                    AND um.idVersion='".self::$apiVersion."'
                    $whereSql
                ORDER BY m.menuPosition";

        $data['modules'] = $database->fetchResultArray($sql);
        $data['subModules'] = self::$apiVersion === 'v1' ? [] : self::getSubModules();

        return $data ? $data : [];
    }

    /**
     * get all avaialable subModules for selected module
     * @return Array subModules array
     */
    private static function getSubModules(){
        global $database;
        $idUserType = self::$user->getIdUserType();

        $sql = "
                SELECT
                  parent.url AS moduleUrl,
                  m.menuName,
                  m.name,
                  m.url
                FROM
                  ".TABLES['modules']." m
                  INNER JOIN
                    (SELECT
                      id,
                      url
                    FROM
                      ".TABLES['modules']." pm
                      INNER JOIN ".TABLES['rel_user_types_modules']." um
                        ON pm.id = um.idModule
                    WHERE um.idUserType = $idUserType
                      AND um.idVersion = '".self::$apiVersion."') parent
                    ON parent.id = m.idParent
                WHERE m.isInMenu = 1
                ORDER BY m.menuPosition";
        $query = $database->query($sql);
        while($row = $database->fetchArray($query)) {
            $data[$row['moduleUrl']][] = $row;
        }

        return $data ? $data : [];
    }

    public static function hasRightsForModule($module){
        global $database;

        if($module === 'login' || $module === 'translate' || $module === 'utils')
            return true;

        $idUserType = self::$user->getIdUserType();
        $sql = "SELECT m.id
                FROM ".TABLES['modules']." m
                INNER JOIN ".TABLES['rel_user_types_modules']." um
                ON m.id=um.idModule
                WHERE um.idUserType=".$idUserType." AND m.name='$module'
                LIMIT 1";
        $query = $database->query($sql);

        return $database->numRows($query) === 1;
    }

    public static function isAPiKeyValid($apiScriptKey){
        if($apiScriptKey === DASH_KEY){
            return true;
        }

        return false;
    }

}
