<?php
/**
 * Manages the transmutation handlers.
 *
 * @package Ealab\Deployer
 */

namespace Ealab\Deployer\Tracking\ItemValueHandler\ValueProcessor\TransmutationHandler;

use Dakwamine\Component\ComponentBasedObject;
use Ealab\Deployer\Exception\WpDeployException;

/**
 * Manages the transmutation handlers.
 *
 * Dev note: this could be factored out for reuse in other managers.
 */
class TransmutationHandlerManager extends ComponentBasedObject {
	/**
	 * List of classes.
	 *
	 * @var array<string,string> The classes, keyed by ID.
	 */
	private static array $class_names;

	/**
	 * Gets the class by its ID.
	 *
	 * To register a new processor, use the "deploy_sync_content__transmutation_handler_manager__get_class_names" filter.
	 *
	 * @param string $id The ID for which to get the class.
	 *
	 * @return class-string<TransmutationHandlerBase> The class name.
	 *
	 * @throws WpDeployException If the ID is invalid.
	 */
	public static function getClassById( string $id ): string {
		if ( empty( $id ) ) {
			throw new WpDeployException( 'The given ID cannot be empty.' );
		}

		$class_name = static::getClasses()[ $id ] ?? null;

		if ( empty( $class_name ) ) {
			throw new WpDeployException( sprintf( 'The given ID "%s" does not exist.', $id ) );
		}

		if ( ! is_a( $class_name, TransmutationHandlerBase::class, true ) ) {
			throw new WpDeployException( 'Invalid class for ID: ' . $id );
		}

		return $class_name;
	}

	/**
	 * Get managed classes.
	 *
	 * @return array<string,class-string> The classes, keyed by their ID.
	 */
	public static function getClasses(): array {
		if ( ! isset( static::$class_names ) ) {
			static::$class_names = apply_filters( 'deploy_sync_content__transmutation_handler_manager__get_class_names', array() );
		}

		return static::$class_names;
	}
}
