<?php
include_once __DIR__ . '/../inc/start.php';

$AjaxResponse = new AjaxResponse();

if(!isPostRequest() || !isRightToken() || !is_admin()) {
	$AjaxResponse->status(false)->alert('Ошибка')->send();
}

const INSTALLER_VERSION = 3.645;
const UPDATE_URL_REGEXP = '#^https://gamecms\.ru/data/HOST_([0-9]{1,2}\.[0-9]{1,3})\(upd\)_[0-9]{1,11}\.zip$#';

if(isset($_POST['install_update'])) {
	ignore_user_abort(1);
	set_time_limit(0);

	set_error_handler (
		function($errno, $errstr) {
			throw new Exception($errstr, $errno);
		}
	);

	try {
		$STH = pdo()->query("SELECT update_link FROM config__secondary LIMIT 1");
		$params = unserialize($STH->fetchColumn());

		$version    = $params['version'];
		$link       = $params['link'];

		global $host;

		$regHost = str_replace('.', '\.', $host);
		$updateUrlRegExp = str_replace('HOST', $regHost, UPDATE_URL_REGEXP);

		if(!preg_match($updateUrlRegExp, $link)) {
			pdo()
				->prepare("UPDATE config__secondary SET update_link=:update_link LIMIT 1")
				->execute([':update_link' => '']);

			throw new Exception('Некорректная ссылка на обновление');
		}

		$versionMatch = [];
		preg_match($updateUrlRegExp, $link, $versionMatch);

		if(empty($versionMatch[1]) || floatval($versionMatch[1]) < INSTALLER_VERSION) {
			throw new Exception('Неверная версия обновления');
		}

		$updatePath = __DIR__ . '/../modules/updates/' . $version . '/';
		$updateInstallersPath = __DIR__ . '/../modules/updates/' . $version . '/installer/';

		$startInstaller = $updateInstallersPath . 'first_installer.php';
		$finishInstaller = $updateInstallersPath . 'second_installer.php';
		$sqlInstaller = $updateInstallersPath . 'base.sql';

		write_log('Начало установки обновления ' . $version);

		if(file_exists($updatePath)) {
			removeDirectory($updatePath);
		}

		if(!mkdir($updatePath, 0777)) {
			throw new Exception('Не удалось создать директорию для обновления');
		}

		$linkParts     = explode('/', $link);
		$updateArchive = end($linkParts);

		$updateFile = $updatePath . $updateArchive;
		file_put_contents($updateFile, file_get_contents($link));

		$archive = new PclZip($updateFile);
		$result  = $archive->extract(PCLZIP_OPT_PATH, $updatePath);


		if(file_exists($startInstaller)) {
			include_once $startInstaller;
		}

		if(file_exists($sqlInstaller)) {
			$sql = trim(file_get_contents($sqlInstaller));

			if(!empty($sql)) {
				pdo()->exec('START TRANSACTION; ' . $sql . ' COMMIT;');
			}
		}

		copy_files($updatePath . 'files/', __DIR__ . '/../');

		if(file_exists($finishInstaller)) {
			include_once $finishInstaller;
		}

		unlink($updateFile);
		removeDirectory($updatePath);
	} catch(Exception $exception) {
		error_log(
			'Ошибка при установке обновления ' . $version . ': '
			. $exception->getMessage()
		);

		exit(json_encode(['status' => 2, 'message' => $exception->getMessage()]));
	}

	tpl()->dell_cache();

	pdo()
		->prepare("UPDATE config SET cache=:cache LIMIT 1")
		->execute([':cache' => configs()->cache + 1]);

	pdo()
		->prepare("UPDATE config__secondary SET version=:version, update_link=:update_link LIMIT 1")
		->execute([':version' => $version, ':update_link' => '']);

	write_log('Установка обновления ' . $version . ' завершена');

	exit(json_encode(['status' => 1]));
}