<?php
$_db_migration_to = '40.03'; // 9.0.0-alpha3
if (!isset($migrations) || !is_object($migrations))
	die("This file cannot be executed directly");
$migrations->CheckValid($_db_migration_to);
//===========================================================================================



$migrations->Run('01_forum_config_migration.php', <<<'DB_UPDATE_FILE'
<?php
/** @var Claromentis\Setup\SetupFacade $migrations */

$coreConfig = $migrations->GetConfigFull('core');
$forumConfig = $migrations->GetConfigFull('forum');

$forumConfigVariables = [
	'cfg_forum_page_size', 'cfg_forum_mode', 'cfg_forum_notification_resp',
	'cfg_forum_rating_phrases', 'cfg_forum_notification_subject',
	'cfg_forum_notify_on_replies', 'cfg_forum_notify_on_topic'
];

foreach ($forumConfigVariables as $forumConfigVariable) {
	$configValue = $coreConfig->get($forumConfigVariable);

	if (isset($configValue)) {
		$forumConfig->set($forumConfigVariable, $configValue);
	}

	$coreConfig->delete($forumConfigVariable);
}

$coreConfig->Save();
$forumConfig->Save();

DB_UPDATE_FILE
);


$migrations->Run('02_style_asset_storage_data_structure_migration.php', <<<'DB_UPDATE_FILE'
<?php
/*
 * Idempotent Migration for updating Themes/the Master Design to a format where the URL for Style assets is derived from their expected locations.
 * This migration will move any assets that do not currently follow the standard format.
 */

/** @var \Claromentis\Setup\SetupFacade $migrations */

$db  = $migrations->GetDb();
$cdn = \Claromentis\Core\Services::I()->GetCDN();

if (!function_exists('updateStyleStorageData'))
{
	/**
	 * Given a Style's data,
	 * updates the format of data for logos, favicons and backgrounds.
	 *
	 * Returns the updated Style's data.
	 *
	 * @param array                              $style
	 * @param string                             $styleCode
	 * @param \Claromentis\Core\CDN\CDNInterface $cdn
	 * @return array
	 */
	function updateStyleStorageData(array $style, string $styleCode, \Claromentis\Core\CDN\CDNInterface $cdn, \Claromentis\Setup\SetupFacade $migrations): array
	{
		$backgroundSizes = ['FHD', '2.7k', '4k UHD'];

		if (isset($style['logo_url']) && is_string($style['logo_url']))
		{
			try {
				$style['logo_extension'] = pathinfo(renameStyleLogo(getStyleAssetCdnPath($style['logo_url']), $styleCode, $cdn), PATHINFO_EXTENSION);
			} catch (Exception $e) {
				$migrations->Log("Failed to update logo url for '$styleCode': " . $e->getMessage());
			}
			unset($style['logo_url']);
		}

		if (isset($style['favicon']) && is_array($style['favicon']))
		{
			foreach ($style['favicon'] as $resolution => $url)
			{
				try {
					renameStyleFavicon(getStyleAssetCdnPath($url), $resolution, $styleCode, $cdn);
					if (!isset($style['favicon_resolutions']))
					{
						$style['favicon_resolutions'] = [];
					}
					$style['favicon_resolutions'][] = $resolution;
				} catch (Exception $e) {
					$migrations->Log("Failed to update favicon for '$styleCode': " . $e->getMessage());
				}
			}
			unset($style['favicon']);
		}

		if (isset($style['page_bg_image']))
		{
			if (is_array($style['page_bg_image']))
			{
				$processedUrls = [];
				foreach ($style['page_bg_image'] as $offset => $url)
				{
					// If we've got all the sizes we want, or if it's a duplicate file reference to one already processed, skip it.
					if (!isset($backgroundSizes[$offset]) || in_array($url, $processedUrls))
					{
						continue;
					}
					try {
						renameStyleBackground(getStyleAssetCdnPath($url), $backgroundSizes[$offset], $styleCode, $cdn);
						if (!isset($style['background_resolutions']))
						{
							$style['background_resolutions'] = [];
						}
						$style['background_resolutions'][] = $backgroundSizes[$offset];
						$processedUrls[]                   = $url;
					} catch (Exception $e) {
						$migrations->Log("Failed to update background image for '$styleCode': " . $e->getMessage());
					}
				}
			} elseif ($style['page_bg_image'] === '')
			{
				$style['background_disabled'] = true;
			}
			unset($style['page_bg_image']);
		}

		return $style;
	}
}

if (!function_exists('getStyleAssetCdnPath'))
{
	/**
	 * Given a Style's Asset's URL Path,
	 * creates and returns the Asset's CDN filepath.
	 *
	 * @param string $url
	 * @return string
	 * @throws Exception If the URL is invalid
	 */
	function getStyleAssetCdnPath(string $url): string
	{
		$urlPath = parse_url($url, PHP_URL_PATH);
		if (!is_string($urlPath))
		{
			throw new Exception("Style has an invalid asset url '$url'");
		}
		$urlPathArray = array_reverse(explode('/', $urlPath));

		return "$urlPathArray[2]/$urlPathArray[1]/$urlPathArray[0]";
	}
}

if (!function_exists('renameStyleLogo'))
{
	/**
	 * Given a Style's Logo's path,
	 * updates the path to the latest standard if incorrect.
	 *
	 * Returns the new path.
	 *
	 * @param string                             $currentPath
	 * @param string                             $styleCode
	 * @param \Claromentis\Core\CDN\CDNInterface $cdn
	 * @return string
	 * @throws \Claromentis\Core\CDN\FileExistsException If a file already exists with that name.
	 * @throws \Claromentis\Core\CDN\NotFoundException If the file to be renamed could not be found.
	 * @throws \Claromentis\Core\CDN\CDNSystemException
	 */
	function renameStyleLogo(string $currentPath, string $styleCode, \Claromentis\Core\CDN\CDNInterface $cdn): string
	{
		$newPath = "theme/{$styleCode}/logo." . pathinfo($currentPath, PATHINFO_EXTENSION);

		if ($currentPath !== $newPath)
		{
			$cdn->RenameFile($currentPath, $newPath);
		}

		return $newPath;
	}
}

if (!function_exists('renameStyleFavicon'))
{
	/**
	 * Given a Style's Favicon's path,
	 * updates the path to the latest standard if incorrect.
	 *
	 * Returns the new path.
	 *
	 * @param string                             $currentPath
	 * @param string                             $resolution
	 * @param string                             $styleCode
	 * @param \Claromentis\Core\CDN\CDNInterface $cdn
	 * @return string
	 * @throws \Claromentis\Core\CDN\CDNSystemException
	 * @throws \Claromentis\Core\CDN\FileExistsException If a file already exists with that name.
	 * @throws \Claromentis\Core\CDN\NotFoundException If the file to be renamed could not be found.
	 */
	function renameStyleFavicon(string $currentPath, string $resolution, string $styleCode, \Claromentis\Core\CDN\CDNInterface $cdn): string
	{
		$newPath = "theme/{$styleCode}/favicon-$resolution.png";

		if ($currentPath !== $newPath)
		{
			$cdn->RenameFile($currentPath, $newPath);
		}

		return $newPath;
	}
}

if (!function_exists('renameStyleBackground'))
{
	/**
	 * Given a Style's background's path,
	 * updates the path to the latest standard if incorrect.
	 *
	 * Returns the new path.
	 *
	 * @param string                             $currentPath
	 * @param string                             $resolution
	 * @param string                             $styleCode
	 * @param \Claromentis\Core\CDN\CDNInterface $cdn
	 * @return string
	 * @throws \Claromentis\Core\CDN\CDNSystemException
	 * @throws \Claromentis\Core\CDN\FileExistsException If a file already exists with that name.
	 * @throws \Claromentis\Core\CDN\NotFoundException If the file to be renamed could not be found.
	 */
	function renameStyleBackground(string $currentPath, string $resolution, string $styleCode, \Claromentis\Core\CDN\CDNInterface $cdn): string
	{
		$newPath = "theme/{$styleCode}/background-$resolution.png";

		if ($currentPath !== $newPath)
		{
			$cdn->RenameFile($currentPath, $newPath);
		}

		return $newPath;
	}
}

$result = $db->query("SELECT id, style FROM theme_style");

while ($row = $result->fetchArray())
{
	$style = json_decode($row['style'], true);
	if (!is_array($style))
	{
		continue;
	}

	$migrations->Log("Updating Style data for Master Design");
	$style = updateStyleStorageData($style, '_default', $cdn, $migrations);

	$styleString = json_encode($style);

	$db->query("UPDATE theme_style SET style = clob:value WHERE id = int:id", $styleString, $row['id']);
}

$result = $db->query("SELECT id, style, code FROM theme");

while ($row = $result->fetchArray())
{
	$style = json_decode($row['style'], true);
	if (!is_array($style))
	{
		continue;
	}

	$migrations->Log("Updating Style data for Theme {$row['code']}");
	$style = updateStyleStorageData($style, $row['code'], $cdn, $migrations);
	$styleString = json_encode($style);

	$db->query("UPDATE theme SET style = clob:value WHERE id = int:id", $styleString, $row['id']);
}

DB_UPDATE_FILE
);


//===========================================================================================
$migrations->SetVersion('40.03');
