<?php

/**
 * Plugin main class.
 *
 * @package WPDesk\DropshippingExport
 */

namespace WPDesk\DropshippingExportFree;

use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\NullLogger;
use DropshippingExportFreeVendor\WPDesk_Plugin_Info;
use DropshippingExportFreeVendor\WPDesk\PluginBuilder\Plugin\AbstractPlugin;
use DropshippingExportFreeVendor\WPDesk\PluginBuilder\Plugin\HookableCollection;
use DropshippingExportFreeVendor\WPDesk\PluginBuilder\Plugin\HookableParent;
use WPDesk\DropshippingExportFree\Config\ActionConfig;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Config\AssetsConfig;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Config\FilesConfig;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Config\MenuConfig;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Config\TemplateConfig;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Config\PluginConfig;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Config\ServiceConfig;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Infrastructure\Config\Abstraction\ConfigInterface;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Infrastructure\Config\Config;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Infrastructure\Service\Container\Abstraction\ServiceContainerAwareInterface;
use DropshippingExportFreeVendor\WPDesk\Library\DropshippingExport\Config\SettingsMenuConfig;
/**
 * Main plugin class. The most important flow decisions are made here.
 *
 * @package WPDesk\DropshippingExport
 */
class Plugin extends AbstractPlugin implements LoggerAwareInterface, HookableCollection {

	const FILTER_PLUGIN_CONFIG = 'wpdesk_dropshipping_export_plugin_config';

	use LoggerAwareTrait;
	use HookableParent;

	/**
	 * Plugin constructor.
	 *
	 * @param WPDesk_Plugin_Info $plugin_info Plugin info.
	 */
	public function __construct( WPDesk_Plugin_Info $plugin_info ) {
		parent::__construct( $plugin_info );
		$this->setLogger( new NullLogger() );

		$this->plugin_url       = $this->plugin_info->get_plugin_url();
		$this->plugin_namespace = $this->plugin_info->get_text_domain();
	}

	/**
	 * Integrate with WordPress and with other plugins using action/filter system.
	 *
	 * @return void
	 */
	public function hooks() { // phpcs:ignore
		parent::hooks();
	}


	/**
	 * Initializes plugin external state.
	 *
	 * The plugin internal state is initialized in the constructor and the plugin should be internally consistent after creation.
	 * The external state includes hooks execution, communication with other plugins, integration with WC etc.
	 *
	 * @return void
	 */
	public function init() {
		add_action(
			'init',
			function () {
				parent::init();
				$config = $this->init_config();

				$service_container_class = $config->get_param( 'service.container' )->get();

				$service_container_class            = $config->get_param( 'service.container' )->get();
				$dependency_resolver_class          = $config->get_param( 'service.resolver' )->get();
				$dependency_binder_collection_class = $config->get_param( 'service.binder_collection' )->get();
				$listener_collection_class          = $config->get_param( 'service.listener_collection' )->get();

				$dependency_binder = new $dependency_binder_collection_class();
				$dependency_binder->add( $config->get_param( 'service.bind' )->get() );
				$dependency_resolver = new $dependency_resolver_class( $dependency_binder );

				$listener_collection = new $listener_collection_class();
				$listener_collection->add( $config->get_param( 'service.listeners' )->get() );

				$service_container = new $service_container_class( $dependency_resolver, $listener_collection );
				if ( $dependency_resolver instanceof ServiceContainerAwareInterface ) {
					$dependency_resolver->set_service_container( $service_container );
				}

				$service_container->add_forbidden( $config->get_param( 'service.forbidden' )->get() );

				$service_container->register_from_array( $config->get_param( 'action' )->get() );
			},
			9
		);
	}

	/**
	 * Undocumented function
	 *
	 * @return void
	 */
	private function init_config(): ConfigInterface {
		$config = new Config();
		$config->register_config(
			\apply_filters(
				self::FILTER_PLUGIN_CONFIG,
				[
					new PluginConfig(
						$this->plugin_info->get_plugin_name(),
						$this->plugin_info->get_text_domain(),
						$this->plugin_info->get_version(),
						$this->plugin_info->get_plugin_file_name(),
						$this->plugin_info->get_plugin_dir()
					),
					new TemplateConfig(),
					new AssetsConfig(),
					new FilesConfig(),
					new ServiceConfig(),
					new ActionConfig(),
					new MenuConfig(),
				]
			)
		);

		return $config;
	}
}
