<?php
declare(strict_types=1);

namespace Ekesto\CacheInvalidator\Core;

/**
 * Lite-safe premium feature detection.
 *
 * The source of truth is the actual availability of premium implementation
 * classes under `src/Invalidator/Pro/` — not the directory itself — so a
 * malformed Lite package that leaves an empty `Pro/` directory behind still
 * resolves to Lite. This file never imports a `Ekesto\CacheInvalidator\Pro\…`
 * class at file scope; premium class names are referenced only as strings
 * through class_exists() so a stripped tree resolves to false without fatals.
 *
 * These flags are the authoritative backend feature gate. React panel hiding is
 * presentation-only and must never be relied on for runtime correctness or as a
 * security/licensing boundary.
 */
final class FeatureFlags
{
    /**
     * Known premium implementation classes used as availability probes.
     *
     * One probe per premium seam (relationships, multilingual, timed, access).
     * String names only — never ::class — so no Pro symbol is referenced from
     * Lite-safe code.
     *
     * @var string[]
     */
    private const PRO_PROBE_CLASSES = [
        'Ekesto\\CacheInvalidator\\Pro\\Relationships\\ProRelationshipProvider',
        'Ekesto\\CacheInvalidator\\Pro\\Multilingual\\ProMultilingualProvider',
        'Ekesto\\CacheInvalidator\\Pro\\Timed\\TimedInvalidationScheduler',
        'Ekesto\\CacheInvalidator\\Pro\\Access\\ProAccessOverrideProvider',
    ];

    /**
     * Whether the premium implementation is actually available.
     *
     * True when at least one known premium implementation class is loadable,
     * which tolerates a partial Pro tree while guaranteeing false for both a
     * fully stripped build and a malformed package with an empty `Pro/`
     * directory.
     *
     * @return bool
     */
    public static function isPremium(): bool
    {
        foreach (self::PRO_PROBE_CLASSES as $proProbeClass) {
            if (class_exists($proProbeClass)) {
                return true;
            }
        }

        return false;
    }

    /**
     * Resolve all premium feature flags.
     *
     * Flags backed by a dedicated premium provider use class_exists() for
     * partial-strip robustness; the remainder fall back to isPremium(). In a full
     * tree all are true; in a stripped Lite tree all are false.
     *
     * @return array<string,bool>
     */
    public static function all(): array
    {
        $premium = self::isPremium();

        return [
            'relationships' => class_exists('Ekesto\\CacheInvalidator\\Pro\\Relationships\\ProRelationshipProvider'),
            'multilingual' => class_exists('Ekesto\\CacheInvalidator\\Pro\\Multilingual\\ProMultilingualProvider'),
            'timedInvalidation' => class_exists('Ekesto\\CacheInvalidator\\Pro\\Timed\\TimedInvalidationScheduler'),
            'postTypeExpansion' => $premium,
            'accessControl' => $premium,
        ];
    }
}
