<?php
/**
 * Generic taxonomy scheduling module.
 *
 * @package ScheduledChanges
 */

namespace ScheduledChanges\Taxonomy;

// phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped -- Exception messages are escaped at UI boundaries.

use ScheduledChanges\Extension\PublicHooks;

/**
 * Resolves explicit taxonomy capability registrations and fails closed.
 */
final class TaxonomyModule {
	public const MODULE_ID = 'scheduled-changes-taxonomies';

	/**
	 * @param TaxonomyRegistration[] $builtins Selected bundled registrations.
	 * @return TaxonomyRegistration[]
	 */
	public function registrations( array $builtins = array() ): array {
		$candidates    = PublicHooks::taxonomyRegistrations( $builtins );
		$registrations = array();

		foreach ( $candidates as $candidate ) {
			if ( ! $candidate instanceof TaxonomyRegistration ) {
				throw new \RuntimeException( 'Taxonomy modules must contribute TaxonomyRegistration objects.' );
			}

			if ( isset( $registrations[ $candidate->id() ] ) ) {
				throw new \RuntimeException( 'Duplicate taxonomy registration: ' . $candidate->id() . '.' );
			}

			$registrations[ $candidate->id() ] = $candidate;
		}

		ksort( $registrations );

		return array_values( $registrations );
	}

	/**
	 * @param TaxonomyRegistration[] $builtins Selected bundled registrations.
	 * @return TaxonomyRegistration[]
	 */
	public function forContext( string $provider_id, string $target_type, array $builtins = array() ): array {
		return array_values(
			array_filter(
				$this->registrations( $builtins ),
				static fn ( TaxonomyRegistration $registration ): bool => $registration->supports( $provider_id, $target_type )
			)
		);
	}
}
