<?php

class AccessManager
{

    public function __construct()
    {
        Yii::import('application.modules.addressbookGeneral.models.*');
        Yii::import('application.modules.adminCalendar.models.*');
        Yii::import('application.modules.adminWebGuiPermissions.models.*');
        Yii::import('application.modules.adminWebGuiPermissions.models.*');
    }

    private $addressbooks;

    private function getDeclaredModules()
    {
        $declaredModules = ModuleManager::getDeclaredModules();
        AccessManager::filterDeclaredModules($declaredModules);
        return $declaredModules;
    }

    public static function filterDeclaredModules(&$declaredModules)
    {
        if (!PhonalisaLicenseManager::analyticsDailyReportEnabled()) {
            unset($declaredModules["analyticsDailyReport"]);
        }

        if (!PhonalisaLicenseManager::analyticsQueueReportEnabled()) {
            unset($declaredModules["analyticsQueueReport"]);
            unset($declaredModules["analyticsAdvancedQueueReport"]);
        }

        if (!PhonalisaLicenseManager::analyticsDailyReportEnabled() && !PhonalisaLicenseManager::analyticsQueueReportEnabled()) {
            unset($declaredModules["analytics"]);
        }

        if (PhonalisaLicenseManager::phonesettingsSpeedDialMax() === 0) {
            unset($declaredModules["phonesettingsSpeedDial"]);
        }

        if (
                !PhonalisaLicenseManager::fax2MailEnabled() &&
                !PhonalisaLicenseManager::missedCall2MailEnabled() &&
                !PhonalisaLicenseManager::sipAccountOffline2MailEnabled() &&
                !PhonalisaLicenseManager::vmail2MailEnabled()
        ) {
            unset($declaredModules["phonesettingsNotifications"]);
        }

        if (!PhonalisaLicenseManager::systemDateTimeProfileEnabled()) {
            unset($declaredModules["systemDateTimeProfile"]);
        }

        if (!PhonalisaLicenseManager::systemAudioFilesEnabled()) {
            unset($declaredModules["systemAudioFiles"]);
            unset($declaredModules["routingIVR"]); // requires systemAudioFiles
        }

        if (!PhonalisaLicenseManager::systemMusicOnHoldEnabled()) {
            unset($declaredModules["systemMusicOnHold"]);
        }

        if (!PhonalisaLicenseManager::routingBlacklistEnabled()) {
            unset($declaredModules["routingBlacklist"]);
        }

        if (!PhonalisaLicenseManager::routingExternalAgentEnabled() && PhonalisaLicenseManager::routingExternalAgentsMax() == 0) {
            unset($declaredModules["routingExternalAgent"]);
        }

        if (!PhonalisaLicenseManager::routingExternalHostEnabled()) {
            $declaredModules["routingExternalHost"]['title'] = 'PHONALISA_CONNECT_SECTION_TITLE';
            $declaredModules["routingExternalHost"]['description'] = 'PHONALISA_CONNECT_SECTION_DESCRIPTION';
        }

        if (PhonalisaLicenseManager::routingQueuesMax() === 0) {
            unset($declaredModules["routingQueues"]);
        }

        if (PhonalisaLicenseManager::routingConferenceMax() === 0) {
            unset($declaredModules["routingConference"]);
        }

        if (PhonalisaLicenseManager::routingIVRMax() === 0) {
            unset($declaredModules["routingIVR"]);
        }

        if (PhonalisaLicenseManager::routingGatewayMax() === 0) {
            unset($declaredModules["routingGateways"]);
            unset($declaredModules["routingInbound"]); // requires routingGateways
            unset($declaredModules["routingOutbound"]); // requires routingGateways
        }
        if (PhonalisaLicenseManager::provisioningKeyProfileMax() === 0) {
            unset($declaredModules["provisioningKeyProfile"]);
        }

        if (PhonalisaLicenseManager::provisioningProfileMax() === 0) {
            unset($declaredModules["provisioningProfile"]);
        }

        if (!PhonalisaLicenseManager::adminBillingEnabled()) {
            unset($declaredModules["adminBilling"]);
        }

        if (!PhonalisaLicenseManager::adminCallForwardingSetsEnabled()) {
            unset($declaredModules["adminCallForwardingSets"]);
        }

        if (!PhonalisaLicenseManager::adminWebGuiPermissionsEnabled()) {
            unset($declaredModules["adminWebGuiPermissions"]);
        }

        if (!PhonalisaLicenseManager::adminCalendarEnabled()) {
            unset($declaredModules["adminCalendar"]);
            unset($declaredModules["calendar"]);
        }

        if (!PhonalisaLicenseManager::adminQueueMonitorEnabled()) {
            unset($declaredModules["routingQueueMonitor"]); // FIXME : Modul should be renamed to adminQueueMonitor
        }

        if (PhonalisaLicenseManager::routingCallGroupMax() === 0) {
            unset($declaredModules["routingCallGroup"]);
        }

        //FIXME ! 
        if (PhonalisaLicenseManager::routingScriptExtensionMax() === 0) {
            unset($declaredModules["routingScriptExtension"]); // FIXME : Modul should be renamed to adminQueueMonitor
        }


        if (!Yii::app()->user->translateMode) {
            unset($declaredModules["systemTranslationTags"]);
        }

        if (!Yii::app()->params->applianceMode) {
            unset($declaredModules["networkSettingsGeneral"]);
            unset($declaredModules["networkAdapterSettings"]);
            unset($declaredModules["networkFirewall"]);
            unset($declaredModules["networkDHCP"]);
            unset($declaredModules["networkDNS"]);
            unset($declaredModules["networkCertificateSettings"]);
            unset($declaredModules["systemUpdate"]);
        }
    }

    private function getUsersModules()
    {
        $permissions = array();
        if (isset(Yii::app()->session['permissions'])) {
            $permissions = Yii::app()->session['permissions'];
        } else {
            $permissions = self::getModulesForCurrentSession();
        }

        return $this->getDeclaredModules();
    }

    private function getAdminPermissions()
    {
        $adminPermissions = array();
        $allModules = $this->getDeclaredModules();

        $adminPermissions = array();
        foreach ($allModules as $name => $attributes) {
            $adminPermissions[$name] = '1';
        }
        return $adminPermissions;
    }

    private function getUsersPermissions()
    {
        $user = app()->user->realUserInstance;
        if ($user) {
            if ($user->isSystemAdmin) {
                return $this->getAdminPermissions();
            }
        } else {
            app()->user->logout();
            app()->user->loginRequired();
        }

        // phonalisa-webinterface-modul
        $group = Groups::model()->findByPk($user->group);
        $permissionOfGroups = array();
        $parentId = $group->parent;
        $parentGroups = array();

        while ($parentId != '0') {
            $parentGroup = Groups::model()->findByPk($parentId);
            $groups[] = $parentGroup;
            $parentId = $parentGroup->parent;
        }
        $groups[] = $group;

        foreach ($groups as $group) {
            if ($group != null) {
                $permissionOfGroups[] = (array) $group->getWebGuiPermissions();
            }
        }

        $mergedPermissions = array();
        foreach ($permissionOfGroups as $processPermissions) {
            if (isset($processPermissions)) {
                $mergedPermissions = array_merge($mergedPermissions, $processPermissions);
            }
        }
        if (!array_key_exists('homeUCItem', $mergedPermissions)) {
            $mergedPermissions['homeUCItem'] = '1';
        }
        if (!array_key_exists('addressbookAddresses', $mergedPermissions)) {
            $mergedPermissions['addressbookAddresses'] = '1';
        }
        if (!array_key_exists('calendarGeneral', $mergedPermissions)) {
            $mergedPermissions['calendarGeneral'] = '1';
        }
        return $mergedPermissions;
    }

    private function getCurrentSection()
    {
        // Current section
        $currentSection = false;
        if (isset(Yii::app()->controller->module->section)) {
            $currentSection = Yii::app()->controller->module->section;
        }
        return $currentSection;
    }

    private function getMainMenuUrl($section, $sideBarSections, $permissions)
    {
        if ($section == 'addressbook') {
            if (count($permissions['read'])) {
                foreach ($permissions['read'] as $id => $attributes) {
                    return '/addressbookAddresses/default/index/';
                }
            }
        } elseif ($section == 'calendar') {
            if (count($permissions['read_calendar'])) {
                foreach ($permissions['read_calendar'] as $id => $attributes) {
                    return '/calendarGeneral';
                }
            }
        } else {
            foreach ($sideBarSections[$section] as $moduleName => $attributes) {
                if (!isset($attributes['type']) || $attributes['type'] != 'main') {
                    return $moduleName;
                }
            }
        }
        return null;
    }

    private function userModules()
    {
        $allModules = $this->getDeclaredModules();
        $permissions = $this->getModulesForCurrentSession();
        $allowedModules = array();

        foreach ($allModules as $modulName => $attributes) {
            if (array_key_exists($modulName, $permissions)) {
                if (isset($attributes['section'])) {
                    $allowedModules[$attributes['section']][$modulName] = $attributes;
                }
            }
        }
        return $allowedModules;
    }

    //after split the PermissionsFile this function is not longer necessary
    private function sortPermissions(&$permissions)
    {
        if (isset($permissions['read'])) {
            $sortedReadPermissions = array();
            foreach ($permissions['read'] as $id => $permission) {
                $sortedReadPermissions[$id] = $permission['itemName'];
            }
            asort($sortedReadPermissions);
            foreach ($sortedReadPermissions as $id => $itemName) {
                $sortedReadPermissions[$id] = $permissions['read'][$id];
            }
            $permissions['read'] = $sortedReadPermissions;
        }

        if (isset($permissions['read_calendar'])) {
            $sortedReadPermissions = array();
            foreach ($permissions['read_calendar'] as $id => $permission) {
                $sortedReadPermissions[$id] = $permission['itemName'];
            }
            asort($sortedReadPermissions);
            foreach ($sortedReadPermissions as $id => $itemName) {
                $sortedReadPermissions[$id] = $permissions['read_calendar'][$id];
            }
            $permissions['read_calendar'] = $sortedReadPermissions;
        }
    }

    public function getPermissions()
    {
        $user = app()->user->sudoUserInstance;

        $permissionModel = new Permissions();
        if (!isset($user)) {

            app()->user->logout();
            app()->user->loginRequired();
        }
        //FIXME !split the PermissionsFile ...
        $usersGroupId = $user->group;
        $userGroup = Groups::model()->findByPk($usersGroupId);
        $groupParentId = $userGroup->parent;
        $groups = array();
        while ($groupParentId != '0') {

            $parentGroup = Groups::model()->findByPk($groupParentId);
            $groupParentId = $parentGroup->parent;
            $groups[] = $parentGroup;
        }
        $groups[] = $userGroup;
        $permissions = array('read' => array(), 'read_calendar' => array());
        foreach ($groups as $group) {
            $groupPermissions = $permissionModel->getPermissionsArray(array('groupId' => $group->id, 'type' => 'read'));
            $permissions['read'] = array_merge($permissions['read'], $groupPermissions);

            $groupPermissions = $permissionModel->getPermissionsArray(
                    array(
                        'groupId' => $group->id,
                        'type' => 'read_calendar'
                    )
            );
            $permissions['read_calendar'] = array_merge($permissions['read_calendar'], $groupPermissions);
        }

        //after split the PermissionsFile this line is not longer necessary
        $this->sortPermissions($permissions);
        //FIXME ! end ...
        return $permissions;
    }

    private function getCalendarPermissions()
    {
        $user = app()->user->realUserInstance;
        $permissionModel = new Permissions();
        $permissions = $permissionModel->getPermissionsArray(
                array(
                    'groupId' => $user->group,
                    'type' => 'read_calendar'
                )
        );
        return $permissions;
    }

    public function getAddressbookItems($permissions)
    {
        //Log::d(" getAddressbookItems", "phonalisa-webinterface-AccessManager");
        $sectionModuleList = array();
        $addressbooks = array();

        foreach ($permissions as $permissionsId => $permissionAttributes) {
            if (!isset($addressbooks[$permissionAttributes['itemId']])) {
                $book = Addressbook::model()->findByPk($permissionAttributes['itemId']);
                if ($book != null) {
                    $addressbooks[$book->title . ' ' . $book->id] = $book;
                }
            }
        }
        ksort($addressbooks);
        foreach ($addressbooks as $bookId => $book) {
            $addressBookModels = array_values($addressbooks);
            $firstAddressBook = array_shift($addressBookModels);

            $sectionModuleList[] = array(
                'label' => $book->title,
                'description' => isset($book->type) ? $book->typeName : '',
                'active' => isset($_REQUEST['id']) ? $_REQUEST['id'] == $book->id : $book->id == $firstAddressBook->id,
                'name' => 'addressbookGeneral',
                'url' => array('/addressbookAddresses/default/index/id/' . $book->id),
                'icon' => str_replace('.png', '', $book->icon)
            );
        }
        return $sectionModuleList;
    }

    //Static Functions
    public static function getMainMenuItems($position = 'top')
    {
        $self = new AccessManager();
        $permissions = $self->getPermissions();
        $modules = $self->getUsersModules();
        $mainSectionItems = array();
        $sideBarSections = array();
        foreach ($modules as $name => $attributes) {
            if (!isset($attributes['type']) || $attributes['type'] != 'main') {
                $sideBarSections [$name] = $attributes;
            } else {
                if ($name == 'addressbookAddresses') {
                    if (!count($permissions['read'])) {
                        continue;
                    }
                }
                if ($name == 'calendar') {
                    if (!count($permissions['read_calendar'])) {
                        continue;
                    }
                }
                $mainSectionItems[$name] = $attributes;
            }
        }
        $mainMenuItems = array();
        $allowedModules = $self->userModules();

        if ($position == 'top') {
            foreach ($mainSectionItems as $moduleName => $attributes) {
                if (array_key_exists($attributes['section'], $allowedModules)) {
                    $mainMenuItems[] = array(
                        // If module has title set it as lable, else display N/a
                        'id' => $attributes['section'] . 'Section',
                        'label' => $attributes['sectionTitle'],
                        'description' => isset($module['description']) ? $attributes['description'] : '',
                        'active' => $self->getCurrentSection() === $attributes['section'] ? true : false,
                        'name' => $moduleName,
                        'url' => array(
                            '/' . $self->getMainMenuUrl(
                                    $attributes['section'], $allowedModules, $permissions
                            )
                        ),
                        'icon' => $attributes['icon'],
                    );
                }
            }
            return $mainMenuItems;
        } elseif ($position == 'sidebar') {
            if ($self->getCurrentSection() == 'addressbook') {
                $mainMenuItems = $self->getAddressbookItems($permissions['read']);
                return $mainMenuItems;
            }
            foreach ($sideBarSections as $moduleName => $attributes) {
                if (!isset($allowedModules[$self->getCurrentSection()])) {
                    continue;
                }
                if ($allowedModules[$self->getCurrentSection()] != null &&
                        array_key_exists($moduleName, $allowedModules[$self->getCurrentSection()])) {
                    if (isset($attributes['section']) && $self->getCurrentSection() === $attributes['section']) {
                        $controllerId = null;
                        $controllerId = app()->controller->module->id;
                        $mainMenuItems[] = array(
                            // If module has title set it as lable, else display N/a
                            'label' => isset($attributes['title']) ? $attributes['title'] : 'N/a',
                            'description' => isset($attributes['description']) ? $attributes['description'] : '',
                            'active' => isset($controllerId) && $controllerId === $moduleName ? true : false,
                            'name' => $moduleName,
                            'url' => array('/' . $moduleName),
                            'icon' => isset($attributes['icon']) ? $attributes['icon'] : 'na.png'
                        );
                    }
                }
            }
            return $mainMenuItems;
        }
    }

    public static function getModulesForCurrentSession()
    {
        $userPermissions = Yii::app()->session['permissions'];
        if ($userPermissions == null) {
            $self = new AccessManager();
            $userPermissions = $self->getUsersPermissions();
            Yii::app()->session['permissions'] = $userPermissions;
        }
        return $userPermissions;
    }

    public static function checkSessionPermission($moduleName)
    {
        if (!app()->user->id) {
            return 'false';
        }

        $allowedModules = self::getModulesForCurrentSession();
        if (!$allowedModules) {
            $allowedModules = array();
        }

        if (array_key_exists($moduleName, $allowedModules)) {
            return "true";
        }
        return "false";
    }

    public static function getSudoUsersListData()
    {
        $user = app()->user->realUserInstance;
        $listData = array();
        $sudoUsers = array_merge(array($user), $user->getSudoUsers());

        foreach ($sudoUsers as $user) {
            $nameIndex = $user->nameindex;
            $extension = (int) $user->extension;
            $id = $user->id;
            $formattedUserName = getFormatedNameToUser($user, 'sudoBar');

            $listData[$nameIndex][$extension][$id] = ' <';
            $listData[$nameIndex][$extension][$id] .= $extension;
            $listData[$nameIndex][$extension][$id] .= '> ';
            $listData[$nameIndex][$extension][$id] .= $formattedUserName;
        }

        $sortedListData = array();
        ksort($listData);
        foreach ($listData as $type => $data) {
            if (is_array($data)) {
                ksort($data);
                foreach ($data as $value => $label) {
                    foreach ($label as $key => $value) {
                        $sortedListData[$type][$key] = $value;
                    }
                }
            } else {
                $sortedListData[$type] = $data;
            }
        }
        return $sortedListData;
    }

    public static function checkDevMode()
    {
        return (string) Yii::app()->params->devMode;
    }

    public static function userSendFaxAllowed($user = array())
    {
        if (!$user) {
            $user = app()->user->sudoUserInstance;
        }
        $faxSendAllowed = User::FAX_SEND_INHERIT_FROM_GROUP;
        if (isset($user->faxSendAllowed) && $user->faxSendAllowed !== '') {
            $faxSendAllowed = $user->faxSendAllowed;
        }

        if ((int) $faxSendAllowed === User::FAX_SEND_INHERIT_FROM_GROUP) {
            $faxSendAllowed = AccessManager::getInheritageSendFaxPermission($user->group);
        }
        return (bool) $faxSendAllowed;
    }

    protected static function getInheritageSendFaxPermission($id)
    {
        $group = Groups::model()->findByPk($id);

        if ($group) {
            if ($group->type === Groups::GROUP_TYPE_ALL_USERS) {
                if (!isset($group->faxSendAllowed)) {
                    $group->faxSendAllowed = User::FAX_SEND_ALLOWED;
                }
                return $group->faxSendAllowed;
            }

            if (!isset($group->faxSendAllowed) || $group->faxSendAllowed === '' || (int) $group->faxSendAllowed === User::FAX_SEND_INHERIT_FROM_GROUP) {
                return AccessManager::getInheritageSendFaxPermission($group->parent);
            }
        }
        return $group->faxSendAllowed;
    }
}
