<?php

namespace {
	/**
	 * Class WP_Statistics_Schedule
	 */
	class WP_Statistics_Schedule {

		/**
		 * WP_Statistics_Schedule constructor.
		 *
		 * @param $WP_Statistics
		 */
		function __construct( $WP_Statistics ) {

			// before construct
			add_filter('cron_schedules', 'WP_Statistics_Schedule::addcron');

			// Add the report schedule if it doesn't exist and is enabled.
			if ( ! wp_next_scheduled('report_hook') && $WP_Statistics->get_option('stats_report') ) {

				wp_schedule_event(time(), $WP_Statistics->get_option('time_report'), 'report_hook');
			}

			// Remove the report schedule if it does exist and is disabled.
			if ( wp_next_scheduled('report_hook') && ! $WP_Statistics->get_option('stats_report') ) {

				wp_unschedule_event(wp_next_scheduled('report_hook'), 'report_hook');
			}

			// Add the GeoIP update schedule if it doesn't exist and it should be.
			if ( ! wp_next_scheduled('wp_statistics_geoip_hook') &&
			     $WP_Statistics->get_option('schedule_geoip') &&
			     $WP_Statistics->get_option('geoip')
			) {

				wp_schedule_event(time(), 'daily', 'wp_statistics_geoip_hook');
			}

			// Remove the GeoIP update schedule if it does exist and it should shouldn't.
			if ( wp_next_scheduled('wp_statistics_geoip_hook') &&
			     ( ! $WP_Statistics->get_option('schedule_geoip') || ! $WP_Statistics->get_option('geoip') )
			) {

				wp_unschedule_event(wp_next_scheduled('wp_statistics_geoip_hook'), 'wp_statistics_geoip_hook');
			}

			// Add the browscap update schedule if it doesn't exist and it should be.
			if ( ! wp_next_scheduled('wp_statistics_browscap_hook') &&
			     $WP_Statistics->get_option('schedule_browscap')
			) {

				wp_schedule_event(time(), 'weekly', 'wp_statistics_browscap_hook');
			}

			// Remove the browscap update schedule if it does exist and it should shouldn't.
			if ( wp_next_scheduled('wp_statistics_browscap_hook') &&
			     ! $WP_Statistics->get_option('schedule_browscap')
			) {

				wp_unschedule_event(wp_next_scheduled('wp_statistics_browscap_hook'), 'wp_statistics_browscap_hook');
			}

			// Add the referrerspam update schedule if it doesn't exist and it should be.
			if ( ! wp_next_scheduled('wp_statistics_referrerspam_hook') &&
			     $WP_Statistics->get_option('schedule_referrerspam')
			) {

				wp_schedule_event(time(), 'weekly', 'wp_statistics_referrerspam_hook');
			}

			// Remove the referrerspam update schedule if it does exist and it should shouldn't.
			if ( wp_next_scheduled('wp_statistics_referrerspam_hook') &&
			     ! $WP_Statistics->get_option('schedule_referrerspam')
			) {

				wp_unschedule_event(
					wp_next_scheduled('wp_statistics_referrerspam_hook'),
					'wp_statistics_referrerspam_hook'
				);
			}

			// Add the database maintenance schedule if it doesn't exist and it should be.
			if ( ! wp_next_scheduled('wp_statistics_dbmaint_hook') && $WP_Statistics->get_option('schedule_dbmaint') ) {

				wp_schedule_event(time(), 'daily', 'wp_statistics_dbmaint_hook');
			}

			// Remove the database maintenance schedule if it does exist and it shouldn't.
			if ( wp_next_scheduled('wp_statistics_dbmaint_hook') &&
			     ( ! $WP_Statistics->get_option('schedule_dbmaint') )
			) {

				wp_unschedule_event(wp_next_scheduled('wp_statistics_dbmaint_hook'), 'wp_statistics_dbmaint_hook');
			}

			// Add the visitor database maintenance schedule if it doesn't exist and it should be.
			if ( ! wp_next_scheduled('wp_statistics_dbmaint_visitor_hook') &&
			     $WP_Statistics->get_option('schedule_dbmaint_visitor')
			) {

				wp_schedule_event(time(), 'daily', 'wp_statistics_dbmaint_visitor_hook');
			}

			// Remove the visitor database maintenance schedule if it does exist and it shouldn't.
			if ( wp_next_scheduled('wp_statistics_dbmaint_visitor_hook') &&
			     ( ! $WP_Statistics->get_option('schedule_dbmaint_visitor') )
			) {

				wp_unschedule_event(
					wp_next_scheduled('wp_statistics_dbmaint_visitor_hook'),
					'wp_statistics_dbmaint_visitor_hook'
				);
			}

			// Remove the add visit row schedule if it does exist and it shouldn't.
			if ( wp_next_scheduled('wp_statistics_add_visit_hook') && ( ! $WP_Statistics->get_option('visits') ) ) {

				wp_unschedule_event(wp_next_scheduled('wp_statistics_add_visit_hook'), 'wp_statistics_add_visit_hook');
			}

			// Add the add visit table row schedule if it does exist and it should.
			if ( ! wp_next_scheduled('wp_statistics_add_visit_hook') && $WP_Statistics->get_option('visits') ) {

				wp_schedule_event(time(), 'daily', 'wp_statistics_add_visit_hook');
			}

			//after construct
			add_action('wp_statistics_add_visit_hook', 'WP_Statistics_Schedule::add_visit_event');
			add_action('wp_statistics_geoip_hook', 'WP_Statistics_Schedule::geoip_event');
			add_action('wp_statistics_browscap_hook', 'WP_Statistics_Schedule::browscap_event');
			add_action('wp_statistics_referrerspam_hook', 'WP_Statistics_Schedule::referrerspam_event');
			add_action('wp_statistics_dbmaint_hook', 'WP_Statistics_Schedule::dbmaint_event');
			add_action('wp_statistics_dbmaint_visitor_hook', 'WP_Statistics_Schedule::dbmaint_visitor_event');
			add_action('report_hook', 'WP_Statistics_Schedule::send_report');

		}

		/**
		 * @param array $schedules
		 *
		 * @return mixed
		 */
		static function addcron( $schedules ) {
			// Adds once weekly to the existing schedules.
			if ( ! array_key_exists('weekly', $schedules) ) {
				$schedules['weekly'] = array(
					'interval' => 604800,
					'display'  => __('Once Weekly'),
				);
			}

			if ( ! array_key_exists('biweekly', $schedules) ) {
				$schedules['biweekly'] = array(
					'interval' => 1209600,
					'display'  => __('Once Every 2 Weeks'),
				);
			}

			if ( ! array_key_exists('4weeks', $schedules) ) {
				$schedules['4weeks'] = array(
					'interval' => 2419200,
					'display'  => __('Once Every 4 Weeks'),
				);
			}

			return $schedules;
		}


		/**
		 * adds a record for tomorrow to the visit table to avoid a race condition.
		 *
		 */
		static function add_visit_event() {
			GLOBAL $wpdb, $WP_Statistics;

			$sqlstring = $wpdb->prepare(
				'INSERT INTO ' .
				$wpdb->prefix .
				'statistics_visit (last_visit, last_counter, visit) VALUES ( %s, %s, %d)',
				$WP_Statistics->Current_Date(null, '+1'),
				$WP_Statistics->Current_date('Y-m-d', '+1'),
				0
			);

			$wpdb->query($sqlstring);
		}

		/**
		 * Updates the GeoIP database from MaxMind.
		 */
		static function geoip_event() {

			GLOBAL $WP_Statistics;

			// Maxmind updates the geoip database on the first Tuesday of the month, to make sure we don't update before they post
			// the update, download it two days later.
			$thisupdate = strtotime(__('First Tuesday of this month', 'wp-statistics')) + ( 86400 * 2 );

			$lastupdate = $WP_Statistics->get_option('last_geoip_dl');

			$upload_dir = wp_upload_dir();

			// We're also going to look to see if our filesize is to small, this means the plugin stub still exists and should
			// be replaced with a proper file.
			$dbsize = filesize($upload_dir['basedir'] . '/wp-statistics/GeoLite2-Country.mmdb');

			if ( $lastupdate < $thisupdate || $dbsize < 1024 ) {

				// We can't fire the download function directly here as we rely on some functions that haven't been loaded yet
				// in WordPress, so instead just set the flag in the options table and the shutdown hook will take care of the
				// actual download at the end of the page.
				$WP_Statistics->update_option('update_geoip', true);
			}
		}

		/**
		 * Updates the browscap database.
		 */
		static function browscap_event() {

			GLOBAL $WP_Statistics;

			// Check for a new browscap once a week
			$WP_Statistics->update_option('update_browscap', true);
		}

		/**
		 * Updates the browscap database.
		 */
		static function referrerspam_event() {

			GLOBAL $WP_Statistics;

			// Check for a new referrerspam once a week
			$WP_Statistics->update_option('update_referrerspam', true);
		}

		/**
		 * Purges old records on a schedule based on age.
		 */
		static function dbmaint_event() {
			global $WP_Statistics;
			if ( ! function_exists('wp_statistics_purge_data') ) {
				require( WP_Statistics::$reg['plugin-dir'] . 'includes/functions/purge.php' );
			}
			$purge_days = intval($WP_Statistics->get_option('schedule_dbmaint_days', false));
			wp_statistics_purge_data($purge_days);
		}

		/**
		 * Purges visitors with more than a defined number of hits in a day.
		 */
		static function dbmaint_visitor_event() {
			global $WP_Statistics;
			if(! function_exists('wp_statistics_purge_visitor_hits')){
				require( WP_Statistics::$reg['plugin-dir'] . 'includes/functions/purge-hits.php' );
			}
			$purge_hits = intval($WP_Statistics->get_option('schedule_dbmaint_visitor_hits', false));
			wp_statistics_purge_visitor_hits($purge_hits);
		}

		/**
		 * Sends the statistics report to the selected users.
		 */
		static function send_report() {
			global $WP_Statistics, $sms;

			// Retrieve the template from the options.
			$final_text_report = $WP_Statistics->get_option('content_report');

			// Process shortcodes in the template.  Note that V8.0 upgrade script replaced the old %option% codes with the appropriate short codes.
			$final_text_report = do_shortcode($final_text_report);
			$final_text_report = apply_filters('wp_statistics_final_text_report_email', $final_text_report);

			// Send the report through the selected transport agent.
			if ( $WP_Statistics->get_option('send_report') == 'mail' ) {

				$blogname  = get_bloginfo('name');
				$blogemail = get_bloginfo('admin_email');

				$headers[] = "From: $blogname <$blogemail>";
				$headers[] = "MIME-Version: 1.0";
				$headers[] = "Content-type: text/html; charset=utf-8";

				if ( $WP_Statistics->get_option('email_list') == '' ) {
					$WP_Statistics->update_option('email_list', $blogemail);
				}

				wp_mail(
					$WP_Statistics->get_option('email_list'),
					__('Statistical reporting', 'wp-statistics'),
					$final_text_report,
					$headers
				);

			} else if ( $WP_Statistics->get_option('send_report') == 'sms' ) {

				if ( class_exists(get_option('wp_webservice')) ) {

					$sms->to  = array( get_option('wp_admin_mobile') );
					$sms->msg = $final_text_report;
					$sms->SendSMS();
				}

			}
		}


	}
}