<?php

class Install {

	//! Instantiate class
	function __construct() {
	}

	/**
	 * @param $f3 \Base
	 */
	public function getInstall($f3){
		$details = array();

		// Version check
		if (version_compare(PHP_VERSION, '5.3.3') >= 0) {
			$details['requirements_version']=1;
		} else {
			$details['requirements_version']=0;
		}

		// Check if cache is writable
		$details['cache_writable']=1;
		try {
			$f3->set('install','test',10);
			if (!$f3->exists('install')) $details['cache_writable']=0;
			$f3->clear('install');
		} catch (Exception $e){
			$details['cache_writable']=0;
		}

		// Check if sqlite pdo driver is enabled
		//if (extension_loaded('sqlite3')){
		if (in_array('sqlite', PDO::getAvailableDrivers())) {
			$details['sql_lite']=1;
		} else {
			$details['sql_lite']=0;
		}

		// Database check
		$db = $f3->get('DB');
		if ($db->exec('SELECT 1')){
			$details['requirements_db']=1;
		} else {
			$details['requirements_db']=0;
		}

		if ($details['requirements_db'] == 0){
			return;
		}

		// Check for existing table whether to install or upgrade
		if (count($db->exec('SHOW TABLES LIKE \'%mysa_%\'')) > 1){

			// Check if logged in
			if (!Account::isLoggedIn()){
				$f3->reroute('/index.php?login&ret='.urlencode(str_replace($f3->get('BASE'), '', $f3->get('URI'))));
			}

			$details = array_merge($details, $this->upgradeDetails($f3));
			$f3->set('finish_button', $f3->get('lang_update'));
			$f3->set('inc','update-part.html');
		} else {
			$details = array_merge($details, $this->installDetails($f3));
			$f3->set('finish_button', $f3->get('lang_finish'));
			$f3->set('inc','install-part.html');
		}

		$f3->set('details',$details);
		echo Template::instance()->render('install.html');

	}


	/**
	 * @param $f3 \Base
	 */
	public function postInstall($f3){
		$response_array = array();
		$response_array['status'] = '';

		/* Setup admin user account */

		if (strlen($f3->get('POST.username')) < 3) {
			$response_array['status'] = 'error';
			$response_array['msg'] = $f3->get('lang_please_enter_a_username');
			echo json_encode($response_array);
			return;
		}
		if (strlen($f3->get('POST.password')) < 6) {
			$response_array['status'] = 'error';
			$response_array['msg'] = $f3->get('lang_please_enter_at_least_6_characters_for_a_password');
			echo json_encode($response_array);
			return;
		}

		/* Setup tables - clear any existing */

		//Confirm config table doesn't exist and it's a valid fresh install
		try {
			if (count($f3->get('DB')->exec('SHOW TABLES LIKE \'%mysa_%\'')) > 1) {
				echo json_encode($response_array);
				return;
			}
		} catch (Exception $e) {
		}

		try {
			\Models\User::setdown();

			// Add Ad and add index
			\Models\Ad::setup();
			$f3->get('DB')->exec('ALTER TABLE mysa_ads ADD KEY `id_status` (`id`,`status`);');

			\Models\Group::setup();

			// Add Sale and add index
			\Models\User::setup();
			$f3->get('DB')->exec('ALTER TABLE mysa_users ADD UNIQUE KEY `username_i` (`username`);ALTER TABLE mysa_users ADD UNIQUE KEY `mail_i` (`mail`(255));');

			// Add Sale and add index
			\Models\Sale::setup();
			$f3->get('DB')->exec('ALTER TABLE mysa_sales ADD KEY `status_site_key` (`status`,`site_key`);');

			// Add Keyword and add index
			\Models\Keyword::setup();
			$f3->get('DB')->exec('ALTER TABLE mysa_keywords ADD KEY `keyword_i` (`keyword`);');

			\Models\Statq::setup();

			// Add stat ad and add index
			\Models\Statad::setup();
			$f3->get('DB')->exec('ALTER TABLE mysa_stats_ads ADD UNIQUE KEY `date_ad_id` (`date`,`ad_id`);');

			// Add stat group and add index
			\Models\Statgroup::setup();
			$f3->get('DB')->exec('ALTER TABLE mysa_stats_groups ADD UNIQUE KEY `date_group_id` (`date`,`group_id`);');

			// Add stat group and add index
			\Models\Statkeyword::setup();
			$f3->get('DB')->exec('ALTER TABLE mysa_stats_keywords ADD UNIQUE KEY `date_keyword_id` (`date`,`keyword_id`);');

			// Add stat landing page and add index
			\Models\Statlandingpage::setup();
			$f3->get('DB')->exec('ALTER TABLE mysa_stats_landing_pages ADD UNIQUE KEY `date_site_key` (`date`,`site_key`);');

			// Add stat sale and add index
			\Models\Statsale::setup();
			$f3->get('DB')->exec('ALTER TABLE mysa_stats_sales ADD UNIQUE KEY `date_sale_id` (`date`,`sale_id`);');

			// Add sales records and add index
			\Models\Salerecord::setup();
			$f3->get('DB')->exec('ALTER TABLE mysa_sales_records ADD KEY `date_sale_id` (`date`,`sale_id`);');

			// Add schedule and add index
			\Models\Schedule::setup();
			$f3->get('DB')->exec('ALTER TABLE mysa_schedule ADD KEY `status_i` (`status`);');

			// Setup session table
			new DB\SQL\Session($f3->get('DB'), 'mysa_sessions', true);
			
		} catch (Exception $e) {
			Utils::Logger('PostInstall: Error setting up db'.$e);
		}



		//Check for user in database
		$user = new \Models\User();
		$user->load(array('username = ?', $f3->get('POST.username')));
		if (!empty($user->username)){
			$response_array['status'] = 'error';
			$response_array['msg'] = $f3->get('lang_error_creating_admin_account') . '. ' . $f3->get
							('lang_please_check_your_settings_or_contact_support');
			echo json_encode($response_array);
			return;
		}

		// Create admin user
		try {
			$user = new \Models\User();
			$user['username'] = $f3->get('POST.username');;
			$user['password'] = $f3->get('POST.password');
			$user['mail'] = $f3->get('POST.mail');
			$user['role'] = 9;
			$user['api'] = sha1(mt_rand().$user['mail']);
			$user->save();
		} catch (Exception $ex){
			$response_array['status'] = 'error';
			$response_array['msg'] = $f3->get('lang_error_creating_admin_account') . '. ' . $f3->get
							('lang_please_check_your_settings_or_contact_support') . '.
			- ' . $ex;
			echo json_encode($response_array);
			return;
		}

		/* Setup config table */
		\Models\Config::setup();
		$config = new \Models\Config();
		$config->mail_from_email = $f3->get('POST.mail');
		$config->purchase_account = $f3->get('POST.purchase_account');
		$config->last_updated = time();
		$config->save();


		/* Download maxmind geolite country and city database */
		$utils = new Utils();
		if (!$utils->GetGeoIPDB($f3, 'country', false)){
			$response_array['status'] = 'warning';
			$response_array['msg'] = $f3->get('lang_please_download_the_latest_geolitecountry_maxmind_database_from_maxmind') .
					' - <a href="http://bit.ly/mmcountrylite">'. $f3->get('lang_download') .'</a> . ' . $f3->get
							('lang_ungzip_it_and_upload_it_to_the_f3_cache_directory');
		}
		if (!$utils->GetGeoIPDB($f3, 'city', false)){
			$response_array['status'] = 'warning';
			$response_array['msg'] = $f3->get('lang_please_download_the_latest_geolitecity_maxmind_database_from_maxmind') .
					' - <a href="http://bit.ly/mmcitylite">'. $f3->get('lang_download') .'</a> . ' . $f3->get
							('lang_ungzip_it_and_upload_it_to_the_f3_cache_directory');
		}

		if ($response_array['status'] == ''){
			$response_array['status'] = 'success';
		}

		echo json_encode($response_array);
	}


	/**
	 * @param $f3 \Base
	 */
	public function postUpdate($f3){

		// Check for DEMO settings
		if ($f3->get('DEMO') == 1) $f3->reroute('/index.php');

		set_time_limit(300); //5 minutes

		$currVersion = $f3->get('VERSION');
		$response_array = array();
		$response_array['status'] = '';

		$md5pa = $f3->get('POST.pa');
		if (empty($md5pa)){
			$response_array['status'] = 'warning';
			$response_array['msg'] = $f3->get('lang_an_update_file_could_not_be_found');
			echo json_encode($response_array);;
			return;
		}

		$zipFilepath= $f3->get('TEMP').$md5pa.'.zip';
		if (!file_exists($zipFilepath)) {
			$response_array['status'] = 'warning';
			$response_array['msg'] = $f3->get('lang_an_update_file_could_not_be_found');
			echo json_encode($response_array);;
			return;
		}

		$rootMysaPath = dirname(__FILE__).'/../../../';
		$rootMysaPath = (DIRECTORY_SEPARATOR === '\\')
				? str_replace('/', '\\', $rootMysaPath)
				: str_replace('\\', '/', $rootMysaPath);

		if (!is_writable($rootMysaPath)){
			$response_array['status'] = 'warning';
			$response_array['msg'] = $f3->get('lang_your_mysimpleads_directory_is_not_writable__please_contact_your_host_or_contact_support_');
			echo json_encode($response_array);
			return;
		}

		// Backup the DB
		\Utils::BackupDB();

		try {
			$zip = new ZipArchive;
			$res = $zip->open($zipFilepath);
			if ($res === TRUE) {
				$zip->extractTo($rootMysaPath);
				$zip->close();
				unlink($zipFilepath);
			} else {
				$response_array['status'] = 'error';
				$response_array['msg'] = $f3->get('lang_there_was_an_error_unzipping_the_update_').' '.$f3->get('lang_please_contact_support_');
				echo json_encode($response_array);
				Utils::Logger('[postUpdate]Couldnt unzip the update.');
				return;
			}
		} catch (Exception $e){
			$response_array['status'] = 'error';
			$response_array['msg'] = $f3->get('lang_there_was_an_error_unzipping_the_update_').' '.$f3->get('lang_please_contact_support_');
			echo json_encode($response_array);
			Utils::Logger('[postUpdate]Error unzipping update - '.$e);
			return;
		}

		// Run any php update files
		// The update files are where ::setup() should be called
		// filename should be version.php (where version is like 201)
		// function in filename should be run_version like function run_201()
		try{
			$updatePath = $rootMysaPath.'updates/';
			$updateFiles = glob($updatePath.'*.php');
			$versionNumber = intval(str_replace('_','',$currVersion));
			if (!empty($updateFiles)){
				foreach ($updateFiles as $updateFile) {
					$baseUpdateFile = basename($updateFile);
					$fileExplode = explode('.',$baseUpdateFile);
					$fileVersion = intval($fileExplode[0]);
					if ($fileVersion>$versionNumber) {
						include_once($updateFile);
						call_user_func('run_'.$fileVersion);
					}
					unlink($updateFile);
				}
			}
		} catch (Exception $e){
			$response_array['status'] = 'error';
			$response_array['msg'] = $f3->get('lang_there_was_a_problem_running_the_update_functions_').' '.$f3->get('lang_please_contact_support_');
			echo json_encode($response_array);
			Utils::Logger('[postUpdate]Error running update functions - '.$e);
			return;
		}

		if ($response_array['status'] == ''){
			$response_array['status'] = 'success';
		}

		// clear all cached files
		\Utils::CleanCache();

		echo json_encode($response_array);
	}


	protected function installDetails(){
		$details = array();

		$details['new_install'] = 1;

		return ($details);
	}

	protected function upgradeDetails(){
		$details = array();

		$config = new \Models\Config();
		$config->load();
		$purchase_account = $config->purchase_account;
		$zipfilename = md5($purchase_account);
		$details['pa'] = $zipfilename;
		$details['new_install'] = 0;

		return ($details);
	}
}
