<?php
/**
 * Registered field providers.
 *
 * @package ScheduledChanges
 */

namespace ScheduledChanges\Provider;

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

use InvalidArgumentException;

/**
 * Request-local provider service registry.
 */
final class ProviderRegistry {
	/**
	 * @var array<string,FieldProvider>
	 */
	private array $providers = array();

	public function register( FieldProvider $provider ): void {
		$id = $provider->id();

		if ( ! preg_match( '/^[a-z][a-z0-9-]*$/', $id ) ) {
			throw new InvalidArgumentException( 'Provider IDs must be lowercase slugs.' );
		}

		if ( isset( $this->providers[ $id ] ) ) {
			throw new InvalidArgumentException( 'Provider already registered: ' . $id );
		}

		$this->providers[ $id ] = $provider;
	}

	/**
	 * @return array<string,FieldProvider>
	 */
	public function all(): array {
		ksort( $this->providers );

		return $this->providers;
	}

	public function get( string $id ): ?FieldProvider {
		return $this->providers[ $id ] ?? null;
	}

	public function count(): int {
		return count( $this->providers );
	}

	/**
	 * @return array<string,string>
	 */
	public function versions(): array {
		$versions = array();

		foreach ( $this->all() as $id => $provider ) {
			$versions[ $id ] = $provider->version();
		}

		return $versions;
	}
}
