<?php

// CLI only
if (PHP_SAPI != 'cli')
{
	die('This script may only be run at the command line.');
}

$fileDir = realpath(dirname(__FILE__) . '/../../../');
chdir($fileDir);

require_once($fileDir . '/library/XenForo/Autoloader.php');
XenForo_Autoloader::getInstance()->setupAutoloader($fileDir . '/library');

XenForo_Application::initialize($fileDir . '/library', $fileDir);
XenForo_Error::setIgnorePendingUpgrade(true);

XenForo_Phrase::setPhrases(require($fileDir . '/install/language_en.php'));
XenForo_Template_Install::setFilePath($fileDir . '/install/templates');

XenForo_Application::get('db')->setProfiler(false); // this causes lots of memory usage in debug mode, so stop that

$dependencies = new XenForo_Dependencies_Install();
$dependencies->preLoadData();

/** @var $upgradeModel XenForo_Install_Model_Upgrade */
$upgradeModel = XenForo_Model::create('XenForo_Install_Model_Upgrade');

/** @var $installModel XenForo_Install_Model_Install */
$installModel = XenForo_Model::create('XenForo_Install_Model_Install');

$cliHelper = new XenForo_Install_CliHelper();

if ($upgradeModel->getNewestUpgradeVersionId() > XenForo_Application::$versionId)
{
	$cliHelper->triggerFatalError('В процессе обновления было обнаружена более новая версия XenForo чем загруженные файлы. Пожалуйста перезалейте все файлы новой версии и перезагрузите страницу.');
}

if ($upgradeModel->getLatestUpgradeVersionId() === XenForo_Application::$versionId
	&& XenForo_Application::get('options')->currentVersionId >= XenForo_Application::$versionId)
{
	//$cliHelper->triggerFatalError('You are already running the latest version.');
}

if (class_exists('XenForo_Install_Data_FileSums'))
{
	$hashes = XenForo_Install_Data_FileSums::getHashes();
	foreach ($hashes AS $key => $hash)
	{
		if (!preg_match('#^(\./)?(install/|library/XenForo/Install/|library/XenForo/Application.php)#', $key))
		{
			unset($hashes[$key]);
		}
	}
	$fileErrors = XenForo_Helper_Hash::compareHashes($hashes);
	$hashesExist = true;
}
else
{
	$fileErrors = array();
	$hashesExist = false;
}

if ($fileErrors)
{
	$cliHelper->printWarning("Некоторые файлы имеют не-оригинальное содержимое:\n\t" . implode("\n\t", $fileErrors) . "\nПродолжайте, только если вы уверены.");
}

$lastCompletedVersion = $upgradeModel->getLatestUpgradeVersionId();

$cliHelper->printMessage(sprintf(
	"Текущая версия: %s\nОбновление: %s (%s)",
	$lastCompletedVersion, XenForo_Application::$versionId, XenForo_Application::$version
), 2);

do
{
	$response = $cliHelper->askQuestion('Вы уверены что хотите обновить? [y/n]');
	if ($cliHelper->validateYesNoAnswer($response, $continue))
	{
		if (!$continue)
		{
			$cliHelper->triggerFatalError("Вы выбрали отказ от обновления. Процесс прерван.");
		}
		break;
	}
}
while (true);

if ($lastCompletedVersion < XenForo_Application::$versionId)
{
	$controller = new XenForo_Install_Controller_Upgrade(
		new Zend_Controller_Request_Http(),
		new Zend_Controller_Response_Http(),
		new XenForo_RouteMatch()
	);

	do
	{
		$nextVersionId = $upgradeModel->getNextUpgradeVersionId($lastCompletedVersion);
		$upgrade = $nextVersionId ? $upgradeModel->getUpgrade($nextVersionId) : false;
		if (!$upgrade)
		{
			break;
		}

		$step = 1;
		$position = 0;
		$data = array();
		$versionName = $upgrade->getVersionName();

		while (method_exists($upgrade, 'step' . $step))
		{
			if ($position)
			{
				$cliHelper->printStatus("Запущено обновление до $versionName, шаг $step ($position)...");
			}
			else
			{
				$cliHelper->printStatus("Запущено обновление до $versionName, шаг $step...");
			}

			$result = $upgrade->{'step' . $step}($position, $data, $controller);
			if ($result instanceof XenForo_ControllerResponse_Abstract)
			{
				$cliHelper->clearStatus();
				$cliHelper->triggerFatalError('Этот шаг должен быть завершён в окне веб-браузера.');
			}
			else if ($result === 'complete')
			{
				$cliHelper->clearStatus(null, "Запущено обновление до $versionName, шаг $step... завершено.");
				break;
			}
			else if ($result === true || $result === null)
			{
				$cliHelper->clearStatus(null, "Запущено обновление до $versionName, шаг $step... завершено.");

				$step++;
				$position = 0;
				$data = array();
			}
			else if (is_array($result))
			{
				// stay on the same step
				$position = $result[0];
				$data = !empty($result[2]) ? $result[2] : array();
			}
			else
			{
				$cliHelper->clearStatus();
				$cliHelper->triggerFatalError('Данный шаг обновления привёл к неожиданному результату.');
			}
		}

		$upgradeModel->insertUpgradeLog($nextVersionId);
		$lastCompletedVersion = $nextVersionId;
	}
	while (true);

	$upgradeModel->insertUpgradeLog();
}

$cliHelper->printMessage("Перестроение / импорт данных...");

/** @var $deferModel XenForo_Model_Deferred */
$deferModel = XenForo_Model::create('XenForo_Model_Deferred');

$installModel->insertDeferredRebuild();

while ($deferModel->runByUniqueKey('installUpgradeRebuild', null, $status))
{
	$cliHelper->printStatus($status);
}

$cliHelper->clearStatus();

if ($upgradeModel->getLatestUpgradeVersionId() === XenForo_Application::$versionId)
{
	$upgradeModel->updateVersion();

	$schemaErrors = $upgradeModel->getDefaultSchemaErrors();
	if ($schemaErrors)
	{
		$cliHelper->printMessage("Обновление завершено, но были найдены ошибки:");
		foreach ($schemaErrors AS $error)
		{
			$cliHelper->printMessage("\t* $error");
		}
		$cliHelper->printMessage("Это похоже на конфликт дополнения. Нужно восстановить из резервной копии, удалить конфликтные данные дополнения из базы данных и повторить обновление. Свяжитесь с поддержкой, если вы не уверены как поступить.");
	}
	else
	{
		$cliHelper->printMessage("Обновление успешно завершено!");
	}
}
else
{
	$cliHelper->printMessage("Ошибка обновления!");
