<?php
/**
 * REST route registrar.
 *
 * @package Carticy\Conversions\Rest
 */

declare(strict_types=1);

namespace Carticy\Conversions\Rest;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * The single place that calls register_rest_route.
 *
 * Centralizing registration keeps the WordPress.org release gate's
 * `register_rest_route` allow-list to exactly one audited file: every admin
 * controller merely declares its routes via {@see AbstractRestController::routes()}
 * and this registrar wires them under the plugin REST namespace with the shared
 * `manage_woocommerce` permission callback.
 */
final class RestApi {

	/**
	 * Admin REST controllers to register.
	 *
	 * @var array<int, AbstractRestController>
	 */
	private array $controllers;

	/**
	 * Constructor.
	 *
	 * @param array<int, AbstractRestController> $controllers Controllers.
	 */
	public function __construct( array $controllers ) {
		$this->controllers = array();
		foreach ( $controllers as $controller ) {
			if ( $controller instanceof AbstractRestController ) {
				$this->controllers[] = $controller;
			}
		}
	}

	/**
	 * Register the REST route hook.
	 */
	public function register_hooks(): void {
		add_action( 'rest_api_init', array( $this, 'register_routes' ) );
	}

	/**
	 * Register every declared route.
	 */
	public function register_routes(): void {
		if ( ! function_exists( 'register_rest_route' ) ) {
			return;
		}

		$namespace = defined( 'CARTICY_CONVERSIONS_REST_NAMESPACE' ) ? CARTICY_CONVERSIONS_REST_NAMESPACE : 'carticy-conversions/v1';

		foreach ( $this->controllers as $controller ) {
			foreach ( $controller->routes() as $route ) {
				if ( ! isset( $route['route'], $route['methods'], $route['callback'] ) ) {
					continue;
				}

				register_rest_route(
					$namespace,
					(string) $route['route'],
					array(
						'methods'             => $route['methods'],
						'callback'            => $route['callback'],
						'permission_callback' => array( $controller, 'can_manage' ),
						'args'                => isset( $route['args'] ) && is_array( $route['args'] ) ? $route['args'] : array(),
					)
				);
			}
		}
	}
}
