<?php
/**
 * Postomatic Plugin - Product Source Detector.
 *
 * PHP Version 5.6
 *
 * @package  Postomatic
 * @category Plugin
 * @license  GPL-2.0-or-later https://www.gnu.org/licenses/gpl-2.0.html
 * @link     https://buildomatics.com/postomatics
 * @since    1.3.0
 */

namespace Postomatic\Api;

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

/**
 * Product_Source_Detector.
 *
 * Single source of truth for "which shop plugin is active on this site".
 *
 * Detection is based exclusively on each platform's own documented,
 * stable markers (a function unique to that plugin, e.g. `wc_get_products()`
 * for WooCommerce, `EDD_VERSION` for Easy Digital Downloads, `sc_get_product()`
 * for SureCart). It deliberately never assumes that a post type literally
 * named "product" belongs to a shop plugin — that was the root cause of
 * Postomatic misidentifying unrelated plugins/themes as an e-commerce store
 * and showing broken "Boost Product Sales" data on sites that don't run any
 * of the supported platforms.
 *
 * Up to 3 platforms are supported, in priority order (first match wins):
 * WooCommerce, Easy Digital Downloads, SureCart.
 *
 * @since 1.3.0
 */
final class Product_Source_Detector {

	/**
	 * Ordered list of supported Product_Source implementations.
	 *
	 * Order matters: on the rare site running more than one shop plugin,
	 * the first active one in this list wins, matching how the rest of the
	 * plugin (single "which platform are we selling on" concept) is meant
	 * to behave.
	 *
	 * @var array<int, class-string<Product_Source_Interface>>
	 */
	private const SOURCE_CLASSES = array(
		Product_Source_Woocommerce::class,
		Product_Source_Easy_Digital_Downloads::class,
		Product_Source_Surecart::class,
	);

	/**
	 * Cached resolved instance for the current request.
	 *
	 * @var Product_Source_Interface|false|null
	 */
	private static $resolved = null;

	/**
	 * Get the active product source for this site, if any.
	 *
	 * @return Product_Source_Interface|null Null when no supported platform is active.
	 */
	public static function get_active_source(): ?Product_Source_Interface {
		if ( null !== self::$resolved ) {
			return false === self::$resolved ? null : self::$resolved;
		}

		foreach ( self::SOURCE_CLASSES as $class ) {
			if ( $class::is_active() ) {
				self::$resolved = new $class();

				return self::$resolved;
			}
		}

		self::$resolved = false;

		return null;
	}

	/**
	 * Whether any supported e-commerce platform is active.
	 *
	 * @return bool
	 */
	public static function has_active_platform(): bool {
		return null !== self::get_active_source();
	}

	/**
	 * Whether the active platform (if any) currently has at least one product.
	 *
	 * @return bool
	 */
	public static function has_products(): bool {
		$source = self::get_active_source();

		return null !== $source && $source->has_products();
	}

	/**
	 * Machine-readable key for the active platform, or empty string if none.
	 *
	 * @return string
	 */
	public static function get_active_platform_key(): string {
		$source = self::get_active_source();

		return null === $source ? '' : $source->get_platform_key();
	}

	/**
	 * Human-readable label for the active platform, or empty string if none.
	 *
	 * @return string
	 */
	public static function get_active_platform_label(): string {
		$source = self::get_active_source();

		return null === $source ? '' : $source->get_platform_label();
	}

	/**
	 * Reset the cached resolution.
	 *
	 * Exposed primarily for tests where multiple platforms are toggled on and
	 * off within the same process.
	 *
	 * @return void
	 */
	public static function reset_cache(): void {
		self::$resolved = null;
	}
}
