<?php
/**
 * Base class for value processors.
 *
 * @package Ealab\Deployer
 */

namespace Ealab\Deployer\Tracking\ItemValueHandler\ValueProcessor;

use Dakwamine\Component\ComponentBasedObject;
use Ealab\Deployer\Exception\WpDeployException;
use Ealab\Deployer\Tracking\ItemValueHandler\ItemValueHandlerBase;
use Ealab\Deployer\Tracking\ItemValueHandler\PlaceholderableTrait;

/**
 * Base class for value processors.
 */
abstract class ValueProcessorBase extends ComponentBasedObject {

	use PlaceholderableTrait;

	/**
	 * The processor instance config.
	 *
	 * The given config depends on the processor.
	 * But it contains at least the ID under the 'id' key.
	 *
	 * @var array<string,mixed>
	 */
	protected array $config = array();

	/**
	 * The object containing this processor. Usually a ItemValueHandlerBase instance.
	 *
	 * @var ItemValueHandlerBase|ComponentBasedObject
	 */
	protected ComponentBasedObject $holder;

	/**
	 * Gets the form build for this value processor.
	 *
	 * @return array The form build.
	 */
	public static function getFormBuild(): array {
		// Default build for html-builder, inserted in a table.
		return array(
			array(
				'type'    => 'td',
				'content' => static::getLabel(),
			),
			array(
				'type'    => 'td',
				'content' => array(
					'load'                => 'processor_item_action_buttons_wrapper',
					'keepTemplateContext' => true,
					'content'             => array(
						'load'                => 'processor_item_three_action_buttons',
						'keepTemplateContext' => true,
					),
				),
			),
		);
	}

	/**
	 * Gets the ID of the processor.
	 *
	 * To override in child classes.
	 *
	 * @return string The ID of the processor.
	 */
	abstract public static function getId(): string;

	/**
	 * The public label for this processor.
	 *
	 * @return string The public label for this processor.
	 */
	abstract public static function getLabel(): string;

	/**
	 * Gets the order of the processor.
	 *
	 * The lower the order, the sooner the processor will be called compared to other processors.
	 * I.e a processor with order 0 will be called before a processor with order 1.
	 *
	 * @return int The priority of the processor.
	 */
	public function getOrder(): int {
		return $this->options['order'] ?? 0;
	}

	/**
	 * Sets the config of this instance.
	 *
	 * @param array                $config The config for this instance.
	 * @param ComponentBasedObject $holder The holder of this processor. Usually a ItemValueHandlerBase.
	 */
	public function init( array $config, ComponentBasedObject $holder ): void {
		$this->config = $config;
		$this->holder = $holder;
	}

	/**
	 * Processes the value.
	 *
	 * @param mixed         $value The value to process.
	 * @param int           $operation The context of operation. See ItemValueHandlerBase::OPERATION__* constants.
	 * @param callable|null $progress_callback The callable called on export/import progress events.
	 *
	 * @return mixed The processed value.
	 *
	 * @throws WpDeployException If the process failed.
	 */
	abstract public function process( $value, int $operation, ?callable $progress_callback = null );
}
