<?php

class Scheduler extends Controller {

	public function processSchedule(){

		// Set a cache key to set scheduler is processing, so doesn't run more than once at a time
		$cache = \Cache::instance();
		if ($cache->exists('s_processing')) return;
		
		$schedule_res = new \Apimodels\Schedule();
		$schedules = $schedule_res->find(array('status=1'), null, 0);
		if (empty($schedules)) return;

		$cache->set('s_processing', 1);
		foreach ($schedules as $schedule){
			if (time() < $schedule->last_run_time + (60 * $schedule->frequency)) continue;

			$result = '';
			switch ($schedule->job){
				case 'limiter':
					$result = $this->_checkLimits();
					$result .= ','.$this->_checkStartEnd();
					break;
				case 'group_click_sort':
					$result = $this->_group_click_sort();
					break;
				case 'cleaner':
					$result = $this->_clean();
					break;
				case 'weekly_emailer':
					$result = $this->_weekly_emailer();
					break;
			}

			$s = new \Apimodels\Schedule();
			$s->load(array('_id=?',$schedule->_id));
			$s->last_run_time = time();
			$s->last_run_result = $result;
			$s->save();
		}

		$cache->clear('s_processing');
	}

	private function _checkStartEnd(){

		$t = time();
		$ad_res = new \Models\Ad();
		$ads = $ad_res->find(array('((status=0 AND start_date<=?) OR (status=1 AND end_date<=?))',$t,$t));
		if (empty($ads)) return ('success');

		try {

			foreach ($ads as $ad) {

				$start = strtotime($ad->start_date);
				$end = strtotime($ad->end_date);

				if ((!empty($start)) && ($ad->status==0) && ($start<=$t)){
					if ((!empty($end)) && ($end <= $t)) continue;
					$a = new \Models\Ad();
					$a->load(array('_id=?',$ad->_id));
					$a->status=1;
					$ad->limit_reached_date=null;
					$a->save();
					continue;
				}

				if (!empty($ad->limit_reached_date)) continue;
				
				if ((!empty($end)) && ($ad->status==1) && ($end<=$t)){
					$a = new \Models\Ad();
					$a->load(array('_id=?',$ad->_id));
					$a->limit_reached_date = $t;
					$a->status=0;
					$a->save();
					Email::sendAdLimitReached($a);
					continue;
				}
			}

		} catch (Exception $e){
			\Utils::Logger('[_checkStartEnd]Error checking start/end dates - '.$e);
			return ('error');
		}

		return ('success');
	}



	private function _checkLimits(){

		$t = time();
		$ad_res = new \Models\Ad();
		$ads = $ad_res->find(array('limit_start_date>0 AND limit_time>0'));
		if (empty($ads)) return ('success');

		try {

			foreach ($ads as $ad) {

				// Start date expired - reset it to now for non-sale ads
				if (($ad->sale_record == null) && (($ad->limit_start_date + strtotime('+'.$ad->limit_time.' days')) < $t)) {
					$a = new \Models\Ad();
					$a->load(array('_id=?',$ad->_id));
					$a->status=1;
					$a->limit_start_date=$t;
					$a->save();
					continue;
				}

				$statad_res = new \Models\Statad();
				$statads = $statad_res->find(array('date >= ? AND ad_id = ?', date('Ymd',$ad->limit_start_date), $ad->_id));
				if (empty($statads)) continue;

				$impressions = 0;
				$clicks = 0;
				foreach ($statads as $statad) {
					$impressions += $statad->impressions;
					$clicks += $statad->$clicks;
				}

				if (!empty($ad->impressions_limit_num)){
					if ($impressions >= $ad->impressions_limit_num){
						$a = new \Models\Ad();
						$a->load(array('_id=?',$ad->_id));
						$a->limit_reached_date = $t;
						$a->status=0;
						$a->save();
						Email::sendAdLimitReached($a);
						continue;
					}
				}

				if (!empty($ad->clicks_limit_num)){
					if ($clicks >= $ad->clicks_limit_num){
						$a = new \Models\Ad();
						$a->load(array('_id=?',$ad->_id));
						$a->limit_reached_date = $t;
						$a->status=0;
						$a->save();
						Email::sendAdLimitReached($a);
						continue;
					}
				}
			}


		} catch (Exception $e){
			\Utils::Logger('[_checkLimits]Error checking limits - '.$e);
			return ('error');
		}

		return ('success');
	}


	private function _group_click_sort(){

		$res_group = new \Models\Group();
		$groups = $res_group->find(array('ad_order_type = ?', 3), null, 1440);
		if (empty($groups)) return ('success');

		$date_start = date('Ymd', strtotime('-7 days'));
		$date_end = date('Ymd');

		$adStats = array();
		foreach ($groups as $group) {

			$ads = $group->ads;
			if (empty($ads)) continue;

			$adIds = '';
			foreach ($ads as $ad){
				$adIds .= $ad->id.',';
			}
			$adIds = trim($adIds,',');

			/** @var $statad Models\Statad */
			$statad_res = new \Models\Statad();
			$statads = $statad_res->find(array('date > ? AND date <= ? AND ad_id IN ('.$adIds.')', $date_start, $date_end), null, 30);
			if (empty($statads)) continue;

			// Add up clicks for each ad for past time period
			foreach ($statads as $statad){
				$ad_id = $statad->ad_id->_id;
				array_key_exists($ad_id, $adStats) ? $adStats[$ad_id] += $statad->clicks : $adStats[$ad_id] = $statad->clicks;
			}

			// Sort by clicks descending
			arsort($adStats);

			// Build custom order
			$order = '';
			foreach($adStats as $key => $value){
				$order .= $key.',';
			}
			$order = trim($order, ',');

			if ($group->ad_order == $order) continue;


			$group_res = new \Models\Group();
			$group_update = $group_res->load(array('_id=?',$group->_id));
			$group_update->ad_order = $order;
			$group_update->save();
		}


		return ('success');
	}


	private function _clean(){
		try {
			$files = glob(dirname(__FILE__)."/../../f3/cache/*.code");
			/*** cycle through all files in the directory ***/
			if (!empty($files)){
				foreach ($files as $file) {
					/*** if file is 30 min (1800 seconds) old then delete it ***/
					if (filemtime($file) < time() - 1800) {
						unlink($file);
					}
				}
			}
			
			$files = glob(dirname(__FILE__)."/../../f3/cache/*.sql");
			/*** cycle through all files in the directory ***/
			if (!empty($files)){
				foreach ($files as $file) {
					/*** if file is 30 min (1800 seconds) old then delete it ***/
					if (filemtime($file) < time() - 1800) {
						unlink($file);
					}
				}
			}

			$files = glob(dirname(__FILE__)."/../../f3/cache/*geocity");
			/*** cycle through all files in the directory ***/
			if (!empty($files)){
				foreach ($files as $file) {
					/*** if file is 12 hours (43200 seconds) old then delete it ***/
					if (filemtime($file) < time() - 43200) {
						unlink($file);
					}
				}
			}

		} catch (Exception $e){
			\Utils::Logger('[_clean]Error cleaning - '.$e);
			return ('error');
		}

		return ('success');
	}

	private function _weekly_emailer(){
		try {
			Email::sendWeeklyStats();
		} catch (Exception $e){
			\Utils::Logger('[_weekly_emailer]Error sending email - '.$e);
			return ('error');
		}

		return ('success');
	}

}