<?php
/**
 * Bootstrap providers and containers.
 *
 * @package Super_Advent_Calendar
 * @author  Verdant Studio
 * @since   1.0.0
 */

namespace SuperAdventCalendar;

/**
 * Exit when accessed directly.
 */
if ( ! defined( 'ABSPATH' )) {
	exit;
}

use SuperAdventCalendar\Interfaces\Providers\AppServiceProviderInterface;

require_once __DIR__ . '/helpers.php';

/**
 * Bootstrap providers and containers.
 */
final class Bootstrap
{
	/**
	 * DI Container.
	 *
	 * @since 1.20.0
	 *
	 * @var Container
	 */
	protected $container;

	/**
	 * Plugin constructor.
	 *
	 * @since 1.0.0
	 */
	public function __construct() {
		$this->container = $this->build_container();
		$this->providers = $this->get_providers();
		$this->register_providers();
		$this->boot_providers();
	}

	/**
	 * Gets all providers.
	 *
	 * @since 1.0.0
	 *
	 * @return array
	 */
	protected function get_providers(): array {
		$providers = array(
			AppServiceProviderInterface::class,
		);

		foreach ( $providers as &$provider ) {
			$provider = $this->container->get( $provider );
		}

		return $providers;
	}

	/**
	 * Registers all providers.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	protected function register_providers(): void {
		foreach ( $this->providers as $provider ) {
			$provider->register();
		}
	}

	/**
	 * Boots all providers.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	protected function boot_providers(): void {
		foreach ( $this->providers as $provider ) {
			$provider->boot();
		}
	}

	/**
	 * Builds the container.
	 *
	 * @since 1.0.0
	 *
	 * @return Container
	 */
	protected function build_container(): Container {
		$container   = new Container();
		$config_path = __DIR__ . '/../config/container.php';

		if ( file_exists( $config_path ) ) {
			$definitions = include $config_path;

			if (is_array( $definitions )) {
				foreach ($definitions as $abstract => $factory) {
					$container->set( $abstract, $factory );
				}
			}
		}

		return $container;
	}
}
