<?php
/**
 * Akeeba Backup Restoration Script
 *
 * @package   brs
 * @copyright Copyright (c)2025 Nicholas K. Dionysopoulos / Akeeba Ltd
 * @license   GNU General Public License version 3, or later
 */

namespace Akeeba\BRS\Platform\Cli\Step;

use Akeeba\BRS\Cli\Step\WriteStepTrait;
use Akeeba\BRS\Framework\Cli\AbstractInstallationStep;
use Akeeba\BRS\Framework\Console\Color;

defined('_AKEEBA') or die();

class Replacedata extends AbstractInstallationStep
{
	use WriteStepTrait;

	public function isApplicable(): bool
	{
		return true;
	}

	public function validate(): void
	{
		// No validation is possible for this step.
	}

	public function execute(): void
	{
		$output = $this->getContainer()->get('output');
		$model  = $this->getContainer()->get('mvcFactory')->model('replacedata');

		$output->heading('Replacing data');

		$replaceFrom = array_keys($this->configuration['replacements'] ?: []);
		$replaceTo   = array_values($this->configuration['replacements'] ?: []);

		$model->setState('replaceFrom', implode("\n", $replaceFrom));
		$model->setState('replaceTo', implode("\n", $replaceTo));
		$model->setState('extraTables', $this->configuration['extraTables'] ?: []);
		$model->setState('replaceguid', $this->configuration['replaceguid'] ?: true);
		$model->setState('min_exec', 0);
		$model->setState('max_exec', 5);
		$model->setState('runtime_bias', 100);
		$model->setState('batchSize', $this->configuration['batchSize'] ?: 10000);
		$model->setState('column_size', $this->configuration['column_size'] ?: 1048576);

		$session = $this->container->get('session');
		$cCyan = new Color('cyan');
		$this->writeStep('Initialising data replacement engine');
		$engine  = $model->init();

		while (true)
		{
			$engine->resetWarnings();

			$engine = $model->step();

			$this->writeStep(
				sprintf(
					'%s %s',
					$cCyan($session->get('brs.replacements.currentTable', '')),
					$session->get('brs.replacements.currentOffset', '')
				)
			);

			$warnings = $engine->getWarnings();

			if ($warnings)
			{
				$output->warningBlock($warnings);
			}

			$more = $model->getState('more', true);

			if (!$more)
			{
				break;
			}
		}
	}

	protected function getDefaultConfiguration(): array
	{
		$model          = $this->getContainer()->get('mvcFactory')->model('Replacedata');
		$replacements   = $model->getReplacements(false, true);
		$extraTables    = $model->getNonCoreTables();
		$deselectTables = $model->getDeselectedTables();
		$dbOptions      = $model->getDatabaseConnectionOptions();
		$prefix         = $dbOptions['prefix'] ?? 'wp_';
		$prefixLen      = strlen($prefix);

		$extraTables = array_filter(
			$extraTables,
			function ($table) use ($prefix, $prefixLen, $deselectTables) {
				return (substr($table, 0, $prefixLen) === $prefix)
				       && !in_array($table, $deselectTables);
			}
		);

		return [
			'replacements' => $replacements,
			'extraTables'  => $extraTables,
			'replaceguid'  => true,
			'column_size'  => 1048576,
			'batchSize'    => 10000,
		];
	}
}