<?php
/**
 * Service provider contract.
 *
 * affilun organizes bootstrap work into small, composable
 * "service providers". Each provider is responsible for registering one
 * cohesive slice of plugin functionality (e.g. REST routes, Gutenberg
 * block registration, admin menu wiring, diagnostics surface, etc.)
 * against the plugin's container and WordPress hook registrar.
 *
 * The {@see \Affilun\Bootstrap\Plugin} bootstrap instantiates
 * each configured provider exactly once and invokes the lifecycle methods
 * in a well-defined order:
 *
 *   1. register()  — pure wiring. Providers bind factories / services into
 *                    the container. No WordPress API calls, no side effects
 *                    beyond the registrar. Runs before WordPress has
 *                    finished loading, so providers MUST NOT depend on
 *                    any hook having fired yet.
 *
 *   2. boot()      — active wiring. Providers may register WordPress hooks
 *                    through the HookRegistrar, read options, and perform
 *                    any setup that requires WordPress to be initialized.
 *                    Called once, after every provider's register() has
 *                    returned, from the plugin's `plugins_loaded` handler.
 *
 * Splitting the lifecycle into two phases guarantees that cross-provider
 * dependencies can be resolved in register() before any provider starts
 * wiring hooks in boot(), which keeps boot order independent of the
 * order providers were configured in.
 *
 * Implementations SHOULD be final and stateless beyond references to
 * collaborators injected into their constructor.
 *
 * @package Affilun\Bootstrap
 */

declare(strict_types=1);

namespace Affilun\Bootstrap;

/**
 * Contract for a unit of bootstrap work.
 *
 * See the file-level docblock for the full lifecycle description.
 */
interface ServiceProvider {

	/**
	 * Bind factories and services into the container.
	 *
	 * Called once, before any provider's {@see ServiceProvider::boot()} is
	 * invoked. Implementations MUST NOT register WordPress hooks or call
	 * any WordPress API from this method; use {@see ServiceProvider::boot()}
	 * for that instead.
	 *
	 * @param ServiceProviderRegistry $registry The registry driving this
	 *                                          bootstrap pass. Providers
	 *                                          may resolve collaborators
	 *                                          from it but SHOULD prefer
	 *                                          constructor injection where
	 *                                          possible.
	 */
	public function register( ServiceProviderRegistry $registry ): void;

	/**
	 * Register WordPress hooks and perform post-registration setup.
	 *
	 * Called once, after every provider's register() has returned.
	 * Implementations SHOULD use the supplied HookRegistrar rather than
	 * calling add_action() / add_filter() directly so that hook wiring
	 * remains inspectable by tests and diagnostics.
	 *
	 * @param HookRegistrar $hooks Thin wrapper over the WordPress hook API.
	 */
	public function boot( HookRegistrar $hooks ): void;
}
