<?php
namespace OfficeBrain\Bundle\AccessManagementBundle\Manager\AbstractManager;

use Symfony\Component\DependencyInjection\ContainerInterface as Container;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Translation\Translator;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Flash\FlashBag;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\JsonResponse;
use Doctrine\Common\Persistence\ObjectManager;
use OfficeBrain\Bundle\AccessManagementBundle\Form\ProjectAccessMasterType;
use OfficeBrain\Bundle\AccessManagementBundle\Form\InstanceUserAccessMappingType;
use OfficeBrain\Bundle\AccessManagementBundle\Form\InstanceAccessMappingType;
use OfficeBrain\Bundle\AccessManagementBundle\Entity\ProjectAccessMaster;
use OfficeBrain\Bundle\AccessManagementBundle\Entity\InstanceUserAccessMapping;
use OfficeBrain\Bundle\AccessManagementBundle\Entity\InstanceAccessMapping;
use OfficeBrain\Bundle\UserBundle\Entity\User;
use OfficeBrain\Bundle\AccessManagementBundle\Entity\InstanceMaster;
use OfficeBrain\Bundle\CoreBundle\Cache\RedisCacheService;

/**
 * @author OfficeBrain 4116 <info@officebrain.com>
 *
 * Description : This Abstract class will manage user level Access.
 *
 **/

abstract class AccessManagementAbstract
{
    protected $serviceContainer;
    protected $entityManager;
    protected $request;
    protected $session;
    
    protected $instanceMasterRepo;
    protected $productAccessMasterRepo;
    protected $instanceAccessMappingRepo;
    protected $instanceUserAccessMappingRepo;
    protected $userRepo;
    protected $statsh_cache_wrapper;
    protected $moduleCachePrefix;
    
    public function __construct($entityManager, $request, $session,$formManager=null)
    {
        $this->entityManager=$entityManager;
        $this->request=$request;
        $this->session=$session;
        $this->formManager=$formManager;
        
        $this->project_setting=$this->request->get('project_setting');
        $this->project_user_setting=$this->request->get('project_user_setting');
        $this->instance_id=$this->project_setting['instance_id'];
        
        $this->statsh_cache_wrapper = RedisCacheService::create();
        $this->moduleCachePrefix = '__AccessManagement__';
    }
    
    public function __destruct()
    {
        unset($this->entityManager);
        unset($this->request);
        unset($this->session);
        unset($this->project_setting);
        unset($this->project_user_setting);
        unset($this->instance_id);
        unset($this->instanceMasterRepo);
        unset($this->productAccessMasterRepo);
        unset($this->projectConfigurationMasterRepo);
        unset($this->instanceAccessMappingRepo);
        unset($this->instanceUserAccessMappingRepo);
        unset($this->userRepo);
        unset($this->statsh_cache_wrapper);
        unset($this->moduleCachePrefix);
    }
    
    /**
    * @author Employee Id: 4116
    * Description :
    *
    * @param 1 : type name desc purpose
    *
    * @return type
    *
    * @throws Exception
    *
    **/
    public function getCurrentUserLoginObject()
    {
        return $this->project_user_setting['user_data'];
    }
    
    public function getFormManager()
    {
        return $this->formManager;
    }
    
    public function getInstanceId()
    {
        return $this->instance_id;
    }
    
    public function setInstanceMasterRepo()
    {
        $this->setAccessManagementRepository('OfficeBrainAccessManagementBundle', 'InstanceMaster');
    }
    
    public function getInstanceMasterRepo()
    {
        if (empty($this->instanceMasterRepo)) {
            $this->setInstanceMasterRepo();
        }
        return $this->instanceMasterRepo;
    }
    
    public function getProjectAccessMasterRepo()
    {
        if (empty($this->productAccessMasterRepo)) {
            $this->setProjectAccessMasterRepo();
        }
        return $this->projectAccessMasterRepo;
    }
    
    public function setProjectAccessMasterRepo()
    {
        $this->setAccessManagementRepository('OfficeBrainAccessManagementBundle', 'ProjectAccessMaster');
    }
    
    public function setAccessManagementRepository($bundleName, $entityName)
    {
        $repoName=lcfirst($entityName).'Repo';
        $this->{$repoName}=$this->entityManager->getRepository("$bundleName:".$entityName);
    }
    
    public function setUserRepository($userRepo=null)
    {
        $this->userRepo=$userRepo;
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for Project Access Master Form Type Object
     * @return ClassInstance
    */
    public function getProjectAccessMasterType()
    {
        return new ProjectAccessMasterType();
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for Project Access Master Entity Object
     * @return ClassInstance
    */
    public function getProjectAccessMaster()
    {
        return new ProjectAccessMaster();
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for Instance User Access Mapping Form Type Entity Object
     * this function we pass user objects as value and Project Access Master Threaded Value
     * @return ClassInstance
    */
    public function getInstanceUserAccessMappingType($objUsers, $objProjectAccessMasters, $userId=0)
    {
        return new InstanceUserAccessMappingType($objUsers, $objProjectAccessMasters, $userId);
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for Instance User Access Mapping Entity Object
     * @return ClassInstance
    */
    public function getInstanceUserAccessMapping()
    {
        return new InstanceUserAccessMapping();
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for Project Access Master Data
     * returns Project Access Master Data as Objects and Order By Parent Ids
     * @return ClassInstance
    */
    public function getProjectAccessMasterData()
    {
        return $this->projectAccessMasterRepo->getAllProjectAccessMasterObject();
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for Project Access Master Data
     * returns Project Access Master Data as Objects and Order By Parent Ids
     * @return ClassInstance
    */
    public function getSubDomianProjectAccessMasterData()
    {
        return $this->projectAccessMasterRepo->getSubDomianProjectAccessMasterData($this->instance_id);
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Instance Access Mapping Object
     * returns Instance Access Mapping Object
     * @return ClassInstance
    */
    public function getInstanceAccessMapping()
    {
        return new InstanceAccessMapping();
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Instance Access Mapping Object
     * returns Instance Access Mapping Object
     * @return ClassInstance
    */
    public function getInstanceAccessMappingType($instanceMaster, $objProjectAccessMasters, $siteId=0)
    {
        return new InstanceAccessMappingType($instanceMaster, $objProjectAccessMasters, $siteId);
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Instance Master Data
     * returns Instance Master Object
     * @return ClassInstance
    */
    public function getInstanceMasterData()
    {
        return $this->instanceMasterRepo->getAllInstanceMasterObject();
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Instance Master Data
     * returns Instance Master Object
     * @return ClassInstance
    */
    public function getSubDomainInstanceMasterData()
    {
        return $this->instanceMasterRepo->getSubDomianInstanceMasterObject($this->instance_id);
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Instance Master Data By ID
     * returns Instance Master Object
     * @return ClassInstance
    */
    public function getSubDomianInstanceMasterByIds($arrIds=array())
    {
        return $this->instanceMasterRepo->getSubDomianInstanceMasterByIds($this->instance_id, $arrIds);
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Instance Master Data By ID
     * returns Instance Master Object
     * @return ClassInstance
    */
    public function getInstanceMasterByIds($arrIds=array())
    {
        return $this->instanceMasterRepo->getAllInstanceMasterByIds($arrIds);
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get User Object by User Id
     * returns Users Data as Objects and Order By username
     * @return UserObj
    */
    public function getUserObjByUserId($userId=0)
    {
        return $this->userRepo->getUserById($userId);
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Parent Project Access Master Data By User Id
     * returns Project Access Master Object Array
     * @return ClassInstance
    */
    public function getParentProjectAccessMasterDataByUserId($objUser)
    {
        return $this->projectAccessMasterRepo->getSubDomianProjectAccessMasterDataByUser($objUser);
    }
    
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Parent Project Access Master Data By Instance Id
     * returns Project Access Master Object Array
     * @return ClassInstance
    */
    public function getProjectAccessMasterDataByInstanceId($instanceId=0)
    {
        return $this->projectAccessMasterRepo->getSubDomianProjectAccessMasterData($instanceId);
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Parent Project Access Master Data By User Id
     * returns Project Access Master Object Array
     * @return ClassInstance
    */
    public function getProjectAccessMasterDataByUserId($userId=0)
    {
        return $this->projectAccessMasterRepo->getProjectAccessMasterDataByUserId($userId);
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for delete Selected Instance User Access Mapping By User
     * @return ClassInstance
    */
    public function deleteSelectedInstanceUserAccessMappingByUser($objUser)
    {
        $this->instanceUserAccessMappingRepo->deleteInstanceUserAccessMappingByUser($objUser);
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Instance User Access Mapping By User
     * @return ClassInstance
    */
    public function getInstanceUserAccessMappingByUser($objUser)
    {
        return $this->instanceUserAccessMappingRepo->getInstanceUserAccessMappingByUser($objUser);
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for delete Instance User Access Mapping By User
     * @return ClassInstance
    */
    public function deleteInstanceUserAccessMappingByUser($objUser, $arrRevokeAccess)
    {
        $this->instanceUserAccessMappingRepo->deleteSubUserInstanceUserAccessMappingByUser($objUser, $arrRevokeAccess);
        foreach ($objUser as $key => $user) {
            foreach ($arrRevokeAccess as $key => $access) {
                // Remove Cache
                if(RedisCacheService::isCacheEnable())
                {
                    $cacheKey1 = $this->moduleCachePrefix. $this->statsh_cache_wrapper->createKey(array('ProjectMasterAccessWiseUserAccess',$access->getId(),$user->getId()));
                    $cacheKey = $this->moduleCachePrefix.$this->statsh_cache_wrapper->createKey(array('InstanceAccessRoutes',$access->getId()));
                    $this->statsh_cache_wrapper->removeAllCache($cacheKey);
                    $this->statsh_cache_wrapper->removeAllCache($cacheKey1);
                }
            }
        }
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get All User Object By Instance Id and User object Array
     * @return ClassInstance
    */
    public function getAllUserObjectByIds($instanceId=0, $arrUser=array())
    {
        return $this->userRepo->getAllUserObjectByIds($instanceId, $arrUser);
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for delete Instance User Access Mapping By Access Id
     * @return ClassInstance
     */
    public function deleteInstanceUserAccessMappingByAccessId($arrObjs=array())
    {
        $this->instanceUserAccessMappingRepo->deleteInstanceUserAccessMappingByAccessId($arrObjs);
        if(RedisCacheService::isCacheEnable())
        {
            $cacheKey1 = $this->moduleCachePrefix.$this->statsh_cache_wrapper->createKey(array('ProjectMasterAccessWiseUserAccess'));
            $this->statsh_cache_wrapper->removeChildCacheOfProject($cacheKey1);
            $cacheKey1 = $this->moduleCachePrefix.$this->statsh_cache_wrapper->createKey(array('InstanceAccessRoutes'));
            $this->statsh_cache_wrapper->removeChildCacheOfProject($cacheKey1);
        }
    }
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for delete All Sub Instance Access Mapping
     * @return ClassInstance
     */
    public function deleteAllSubInstanceAccessMapping($arrRevokeAccess)
    {
        $this->instanceAccessMappingRepo->deleteAllSubInstanceAccessMapping($arrRevokeAccess);
        if(RedisCacheService::isCacheEnable())
        {
            $cacheKey1 = $this->moduleCachePrefix.$this->statsh_cache_wrapper->createKey(array('ProjectMasterAccessWiseUserAccess'));
            $this->statsh_cache_wrapper->removeChildCacheOfProject($cacheKey1);
            $cacheKey1 = $this->moduleCachePrefix.$this->statsh_cache_wrapper->createKey(array('InstanceAccessRoutes'));
            $this->statsh_cache_wrapper->removeChildCacheOfProject($cacheKey1);
        }
    }
    
        /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for delete Instance User Access Mapping By Instance Id
     * @return ClassInstance
    */
    public function deleteInstanceUserAccessMappingByInstanceId($instance, $arrObjs=array())
    {
        $this->instanceUserAccessMappingRepo->deleteInstanceUserAccessMappingByInstanceId($instance, $arrObjs);
        if(RedisCacheService::isCacheEnable())
        {
            foreach ($arrObjs as $key => $value) {
                // Remove Cache
                $cacheKey1 = $this->moduleCachePrefix.$this->statsh_cache_wrapper->createKey(array('ProjectMasterAccessWiseUserAccess',$instance->getId(),$value->getId()));
                $cacheKey = $this->moduleCachePrefix.$this->statsh_cache_wrapper->createKey(array('InstanceAccessRoutes',$instance->getId()));
                $this->statsh_cache_wrapper->removeAllCache($cacheKey);
                $this->statsh_cache_wrapper->removeAllCache($cacheKey1);
            }
        }
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Project Access Master Data By Ids
     * @return ClassInstance
    */
    public function getProjectAccessMasterDataByIds($arrIds)
    {
        return $this->projectAccessMasterRepo->getProjectAccessMasterDataByIds($arrIds);
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for getUserProjectAccessMasterDataByIds
     * @return ClassInstance
    */
    public function getUserProjectAccessMasterDataByIds($instanceId, $arrIds)
    {
        return $this->projectAccessMasterRepo->getSubDomianProjectAccessMasterDataByIds($instanceId, $arrIds);
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get SubDomian Project Access Master Data By Ids
     * @return ClassInstance
    */
    public function getSubDomianProjectAccessMasterDataByIds($arrIds)
    {
        return $this->projectAccessMasterRepo->getSubDomianProjectAccessMasterDataByIds($this->instance_id, $arrIds);
    }

    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for check for Main Site Access Exists
     * @return ClassInstance
    */
    public function isMainSiteAccessExists()
    {
        return count($this->instanceAccessMappingRepo->getMainInstanceAccessMappingObjects())>0?true:false;
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for delete Instance Access Mapping By Instance Id
     * @return ClassInstance
    */
    public function deleteInstanceAccessMappingByInstanceId($instance)
    {
        $this->instanceAccessMappingRepo->deleteInstanceAccessMappingByInstanceId($instance);
        if(RedisCacheService::isCacheEnable())
        {
            $cacheKey1 = $this->moduleCachePrefix.$this->statsh_cache_wrapper->createKey(array('ProjectMasterAccessWiseUserAccess'));
            $this->statsh_cache_wrapper->removeChildCacheOfProject($cacheKey1);
            $cacheKey1 = $this->moduleCachePrefix.$this->statsh_cache_wrapper->createKey(array('InstanceAccessRoutes'));
            $this->statsh_cache_wrapper->removeChildCacheOfProject($cacheKey1);
        }
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for get Instance Access Mapping By Instance Id
     * @return ClassInstance
    */
    public function getInstanceAccessMappingByInstanceId($instance)
    {
        return $this->instanceAccessMappingRepo->getInstanceAccessMappingByInstanceId($instance);
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for Project Access Master Data
     * returns Project Access Master Data as Objects and Order By Parent Ids
     * @return ClassInstance
    */
    public function getAllConfigurationMasterData()
    {
        return $this->projectConfigurationMasterRepo->getAllConfigurationMasterObject();
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created for Project Access Master Data
     * returns Project Access Master Data as Objects and Order By Parent Ids
     * @return ClassInstance
    */
    public function getAllConfigurationInstanceData()
    {
        return $this->instanceConfigurationRepo->getAllConfigurationInstanceObject($this->instance_id);
    }
    
    /**
     * @author Employee Id: 4116
     * OB eCommerce Product - Assess Management
     * Function created is Abstract method
     * returns Project Access Master Data as Objects and Order By Parent Ids
     * @return ClassInstance
    */
    public function saveAccessData($request)
    {
        // this is simple save Access Data Method which Override Site Extened Class
    }
    
    /**
     * @author Employee Id: 4465
     * OB eCommerce Product - Assess Management
     * Function created to get access rules of main site
     * @return ClassInstance
     */
    public function getMainSiteAccessRules()
    {
        return $this->instanceAccessMappingRepo->getMainInstanceAccessMappingObjects();
    }
}
