<?php
/**
 * Registry of third party integrations.
 *
 * @package MenuVerse
 */

namespace WPXero\MenuVerse\Compat;

defined( 'ABSPATH' ) || exit;

/**
 * Keeps track of which other plugins MenuVerse can cooperate with.
 *
 * Like the module registry, this stores class names rather than instances. An
 * integration whose plugin is absent is never constructed, so it costs nothing
 * beyond one `class_exists` style check.
 */
class Integration_Registry {

	/**
	 * Registered integration class names, keyed by identifier.
	 *
	 * @var array<string, string>
	 */
	private $integrations = array();

	/**
	 * Registers the integrations that ship with the plugin.
	 *
	 * @return void
	 */
	public function boot() {
		$this->register( Woo::class );
		$this->register( Edd::class );
		$this->register( Yith_Wishlist::class );
		$this->register( Popup_Maker::class );

		/**
		 * Fires so add ons can register their own integrations.
		 *
		 * @since 1.0.0
		 *
		 * @param Integration_Registry $registry Integration registry.
		 */
		do_action( 'menuverse_register_integrations', $this );
	}

	/**
	 * Registers one integration by class name.
	 *
	 * @param string $class_name Class implementing the Integration interface.
	 * @return void
	 */
	public function register( $class_name ) {
		if ( ! is_subclass_of( $class_name, Integration::class ) ) {
			return;
		}

		$this->integrations[ $class_name::id() ] = $class_name;
	}

	/**
	 * Tells whether one integration is available.
	 *
	 * @param string $id Integration identifier.
	 * @return bool
	 */
	public function is_active( $id ) {
		if ( ! isset( $this->integrations[ $id ] ) ) {
			return false;
		}

		return (bool) $this->integrations[ $id ]::is_active();
	}

	/**
	 * Returns the active state of every registered integration.
	 *
	 * Feeds the dashboard, where it drives the `ui.requires` hint that explains
	 * why a setting is unavailable instead of silently hiding it.
	 *
	 * @return array<string, bool>
	 */
	public function status() {
		$status = array();

		foreach ( $this->integrations as $id => $class_name ) {
			$status[ $id ] = (bool) $class_name::is_active();
		}

		return $status;
	}
}
