<?php
/**
 * Service Provider Manager
 *
 * Manages service providers and their registration
 *
 * @package NemtlyBooking
 * @since   PBOOKING_SINCE
 */

namespace NemtlyBooking\Core;

use NemtlyBooking\Interfaces\Service_Provider_Interface;

/**
 * Service Provider Manager class
 *
 * @since PBOOKING_SINCE
 */
class Service_Provider_Manager {

    /**
     * Container instance
     *
     * @var Container
     */
    private $container;

    /**
     * Registered service providers
     *
     * @var Service_Provider_Interface[]
     */
    private $providers = [];

    /**
     * Booted service providers
     *
     * @var Service_Provider_Interface[]
     */
    private $booted_providers = [];

    /**
     * Constructor
     *
     * @since PBOOKING_SINCE
     *
     * @param Container $container The dependency injection container.
     */
    public function __construct( Container $container ) {
        $this->container = $container;
    }

    /**
     * Register a service provider
     *
     * @since PBOOKING_SINCE
     *
     * @param Service_Provider_Interface $provider Service provider instance.
     */
    public function register( Service_Provider_Interface $provider ) {
        $provider_name = get_class( $provider );

        if ( isset( $this->providers[ $provider_name ] ) ) {
            return;
        }

        $provider->register( $this->container );
        $this->providers[ $provider_name ] = $provider;
    }

    /**
     * Boot all registered service providers
     *
     * @since PBOOKING_SINCE
     */
    public function boot() {
        foreach ( $this->providers as $provider ) {
            if ( ! in_array( $provider, $this->booted_providers, true ) ) {
                $provider->boot( $this->container );
                $this->booted_providers[] = $provider;
            }
        }
    }

    /**
     * Get all registered providers
     *
     * @since PBOOKING_SINCE
     *
     * @return Service_Provider_Interface[]
     */
    public function get_providers() {
        return $this->providers;
    }

    /**
     * Get all booted providers
     *
     * @since PBOOKING_SINCE
     *
     * @return Service_Provider_Interface[]
     */
    public function get_booted_providers() {
        return $this->booted_providers;
    }

    /**
     * Check if a provider is registered
     *
     * @since PBOOKING_SINCE
     *
     * @param string $provider_class Provider class name.
     *
     * @return bool
     */
    public function is_registered( $provider_class ) {
        return isset( $this->providers[ $provider_class ] );
    }

    /**
     * Check if a provider is booted
     *
     * @since PBOOKING_SINCE
     *
     * @param string $provider_class Provider class name.
     *
     * @return bool
     */
    public function is_booted( $provider_class ) {
        foreach ( $this->booted_providers as $provider ) {
            if ( get_class( $provider ) === $provider_class ) {
                return true;
            }
        }
        return false;
    }
}
