<?php
/**
* @package XenCentral Ad Server
* @author Skydevelop EU
* @copyright Drnoyan & Nalyan LDA, Portugal, EU
* @license http://www.dnf.pt/eula.html
* @link http://www.skydevelop.com
* @revision 97
* @version 2.0.0 beta 3 rev. 3
*/

class XenCentral_AdServer_ControllerPublic_Delivery extends XenCentral_AdServer_ControllerPublic_Abstract
{
    public function canUpdateSessionActivity($controllerName, $action, &$newState)
    {
        return false;
    }

    protected function _assertViewingPermissions($action)
    {

    }


    protected function _assertIpNotBanned()
    {

    }

    protected function _assertNotBanned()
    {

    }

    protected function _preDispatch($action)
    {
        parent::_preDispatch($action);

        if($action!=='Index') {
            return;
        }

        // disabled cache check
        return;

        $input = $this->getInput()->filter(array(
                'requestId' => XenForo_Input::STRING
        ));

        if(!$input['requestId']) {
            return;
        }

        $cacheId='request_'.md5($input['requestId']);


        $count=0;
        while($isCached=$this->_getCacheModel()->load($cacheId)) {
            usleep(100000);
            $count++;
            if($count>10) {
                $this->_getCacheModel()->remove($cacheId);
                break;
            }
        }

        $this->_getCacheModel()->save(1, $cacheId, array(), 1);
    }

    protected function _postDispatch($controllerResponse, $controllerName, $action)
    {
        parent::_postDispatch($controllerResponse, $controllerName, $action);

        if ($action !== 'Index') {
            return;
        }

        $input = $this->getInput()->filter(array(
                'requestId' => XenForo_Input::STRING
        ));

        if (!$input['requestId']) {
            return;
        }

        $cacheId = 'request_' . md5($input['requestId']);

        $this->_getCacheModel()->remove($cacheId);
    }


    public function actionIndex()
    {
        $singleRequestParams=array(
            'zones' => XenForo_Input::STRING,
            'bannerId' => XenForo_Input::UINT,
            'randomId' => XenForo_Input::STRING,
            'safeModeLoaded' => XenForo_Input::STRING,
        );

        $initialInput = $this->getInput()->filter(array(
            'requestId' => XenForo_Input::STRING,
            'bR' => XenForo_Input::ARRAY_SIMPLE,
            'batchRequest' => XenForo_Input::ARRAY_SIMPLE,
        )+$singleRequestParams);

        if(empty($initialInput['bR']) AND !empty($initialInput['batchRequest'])) {
            $initialInput['bR']= $initialInput['batchRequest'];
        }

        if($initialInput['zones'] OR $initialInput['bannerId']) {
            $initialInput['bR'][$initialInput['randomId']]['zones']= $initialInput['zones'];
            $initialInput['bR'][$initialInput['randomId']]['bannerId']= $initialInput['bannerId'];
            $initialInput['bR'][$initialInput['randomId']]['safeModeLoaded']= $initialInput['safeModeLoaded'];
            $initialInput['bR'][$initialInput['randomId']]['randomId']= $initialInput['randomId'];
        }

        $deliveryGroups=array();

        foreach($initialInput['bR'] AS $randomId=>$input) {
            $inputCleaner=new XenForo_Input($input);

            $input=$inputCleaner->filter($singleRequestParams);

            $input['requestId'] = $initialInput['requestId'];

            $zoneIdList = explode(',', $input['zones']);
            $zoneIdList=array_map('intval', $zoneIdList);

            $bannerCache = $this->_getBannerModel()->getActiveBanners();
            if($input['bannerId'] AND isset($bannerCache[$input['bannerId']])) {
                $banner=$bannerCache[$input['bannerId']];
                $zones=$this->_getZoneModel()->getAllActiveZones();
                $zones=array($banner['zoneId']=>$zones[$banner['zoneId']]);
            } else {
                $zones = $this->_getZoneModel()->getActiveZones();
            }

            foreach ($zones AS $zoneId => $zone) {
                if (!in_array($zoneId, $zoneIdList)) {
                    unset($zones[$zoneId]);
                }
            }

            // check for banners loaded in safe mode and remove appropriate zones if rotation enabled
            if ($input['safeModeLoaded']) {
                $loadedBanners = explode(',', $input['safeModeLoaded']);

                foreach ($loadedBanners AS $loadedBannerId) {
                    if (!$loadedBannerId) {
                        continue;
                    }
                    if (!isset($bannerCache[$loadedBannerId])) {
                        continue;
                    }
                    $banner = $bannerCache[$loadedBannerId];

                    if (!isset($zones[$banner['zoneId']])) {
                        continue;
                    }
                    $zone = $zones[$banner['zoneId']];
                    if ($zone->rotateBanners()) {
                        unset($zones[$zone->getZoneId()]);
                    }
                }
            }

            if (empty($zones)) {
                continue;
            }

            $autoRotate = 0;

            if ($input['bannerId']) {
                // force one zone only
                $zone=array_shift($zones);
                $zones = array($zone->getZoneId()=>$zone);
            }

            // now we have zones to be displayed, get banners from them
            /** @var XenCentral_AdServer_Zone[] $standardZones */
            /** @var XenCentral_AdServer_Zone[] $rotatedZones */
            $standardZones = $rotatedZones = array();
            foreach ($zones AS $zone) {
                if (!$zone->getActiveBanners() AND empty($input['bannerId'])) {
                    // do not count zones without banners
                    continue;
                }

                if($zone->isCustomZone()) {
                    // No need to check this, as the banners need to be paused automatically when users don't have credit anymore
                    /* if(!$zone->getActiveOwnerUserInfo($zone->getCostPerClick())) {
                        // doesn't have any owner with proper amount of credits
                        continue;
                    } */

                    if($zone->isValidHttpReferer(
                            $this->getRequest()->getServer('HTTP_REFERER')
                        )===false
                    ) {
                        continue;
                    }
                }

                if ($zone->rotateZone()) {
                    $rotatedZones[$zone->getZoneId()] = $zone;
                } else {
                    $standardZones[$zone->getZoneId()] = $zone;
                }
            }

            if ($rotatedZones) {
                $rotatedZoneIds = array_keys($rotatedZones);
                shuffle($rotatedZoneIds);
                $rotateZoneId = reset($rotatedZoneIds);
                $standardZones = array(
                        $rotateZoneId => $rotatedZones[$rotateZoneId]
                    ) + $standardZones;
            }

            $randomId=$input['randomId'];
            $groupedBanners=array();

            $zoneImpressions = $bannerImpressions = array();

            foreach ($standardZones AS $zone) {
                /** @var XenCentral_AdServer_Model_BannerRotator $bannerRotator */
                $bannerRotator = XenForo_Model::create('XenCentral_AdServer_Model_BannerRotator');
                $bannerRotator->setOnlyBannerId($input['bannerId']);
                $bannerRotator->setRotateBanners($zone->rotateBanners());
                $bannerRotator->setRandomizeBanners($zone->randomizeBanners());

                if (empty($input['bannerId'])) {
                    // zone impression is counted only when zone is being delivered, not a separate banner
                    $zoneImpressions[] = $zone->getZoneId();
                }

                if ($zone->getAutoRotateInterval()) {
                    if (!$autoRotate) {
                        $autoRotate = $zone->getAutoRotateInterval();
                    } else {
                        $autoRotate = min($autoRotate, $zone->getAutoRotateInterval());
                    }
                }

                $banners = $zone->getActiveBanners();
                if (empty($banners)) {
                    continue;
                }

                $bannerRotator->setBanners($banners);

                $banners = $bannerRotator->getProcessedBanners($input['requestId']);

                $banners=$this->_getBannerModel()->prepareBanners($banners);

                $bannerContent = "";

                foreach ($banners AS $banner) {
                    if ($banner['status'] == 'active' AND !$input['bannerId']) {
                        $bannerImpressions[] = $banner['bannerId'];
                        $this->_getCappingModel()->saveBannerImpression($banner['bannerId']);
                    }
                    
                    $groupedBanners["zone{$zone->getZoneId()}"][]=$banner;
                }
            }

            $this->_getStatsModel()->storeImpressionLogs($bannerImpressions, $zoneImpressions);

            $autoRotate = 1000 * $autoRotate;

            $deliveryGroups[$randomId]=array(
                'randomId'=>$randomId,
                'groupedBanners'=>$groupedBanners,
                'autoRotate'=>$autoRotate
            );
        }
        $this->_routeMatch->setResponseType('raw');

        return $this->responseView('XenCentral_AdServer_ViewPublic_Delivery', '', array(
                'deliveryGroups'=>$deliveryGroups
            ) + $this->_getDeliveryHelper()->getDeliveryFrameworkParams());
    }

    /**
     * @return XenCentral_AdServer_ControllerHelper_Delivery
     */
    protected function _getDeliveryHelper()
    {
        return $this->getHelper('XenCentral_AdServer_ControllerHelper_Delivery');
    }

    protected function _getScriptResponse($script)
    {
        $this->_routeMatch->setResponseType('raw');
        return $this->responseView('XenCentral_AdServer_ViewPublic_Delivery', '', array(
            'script' => $script
        ));
    }

    /**
     * @return XenCentral_AdServer_Model_Stats
     */
    protected function _getStatsModel()
    {
        return $this->getModelFromCache('XenCentral_AdServer_Model_Stats');
    }

    /**
     * @return XenCentral_AdServer_Model_Capping
     */
    protected function _getCappingModel()
    {
        return $this->getModelFromCache('XenCentral_AdServer_Model_Capping');
    }

    /**
     * @return XenCentral_Framework_Model_Cache
     */
    protected function _getCacheModel()
    {
        return $this->getModelFromCache('XenCentral_Framework_Model_Cache');
    }
}