<?php
/**
 * BaseCloud Boost — Object Cache (Redis / Object Cache Pro / Memcached) Compatibility
 *
 * BaseCloud Boost is a *page* cache. A persistent *object* cache (Object Cache
 * Pro, Redis Object Cache, Memcached) is a complementary, lower layer that caches
 * database queries and WordPress objects. The two are designed to run together —
 * the worry is only that a page-cache plugin might clash with the object cache.
 *
 * This layer guarantees there is no clash:
 *
 *   1. We never ship an `object-cache.php` drop-in, so we can't collide with the
 *      object cache's own drop-in (we only install `advanced-cache.php`).
 *   2. We never call wp_cache_flush() — wiping the whole object cache on a page
 *      purge would defeat its purpose and hammer the database.
 *   3. Any short-lived data we keep in the object cache is registered as a
 *      non-persistent group, so it never bloats Redis/Object Cache Pro.
 *
 * @package BaseCloud\Boost\Compatibility
 */

declare( strict_types=1 );

namespace BaseCloud\Boost\Compatibility;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Ensures friction-free coexistence with a persistent object cache.
 */
class Object_Cache_Compat {

	/** @var string Cache group used by BaseCloud Boost. */
	public const GROUP = 'bcboost';

	/**
	 * Register non-persistent groups so transient/object writes never persist to
	 * Redis/Memcached and can't bloat the object cache.
	 *
	 * @return void
	 */
	public function boot(): void {
		if ( function_exists( 'wp_cache_add_non_persistent_groups' ) ) {
			wp_cache_add_non_persistent_groups( [ self::GROUP ] );
		}
	}

	/**
	 * Whether a persistent (external) object cache is active.
	 *
	 * @return bool
	 */
	public static function is_active(): bool {
		return function_exists( 'wp_using_ext_object_cache' ) && wp_using_ext_object_cache();
	}

	/**
	 * Human-readable name of the active object cache backend, or '' if none.
	 *
	 * Identifies Object Cache Pro, the free Redis Object Cache, and Memcached by
	 * inspecting the active $wp_object_cache implementation class — no dependency
	 * on a specific plugin constant.
	 *
	 * @return string
	 */
	public static function backend(): string {
		if ( ! self::is_active() ) {
			return '';
		}

		// Identify the backend from the active object-cache implementation class —
		// no dependency on plugin-specific constants. Object Cache Pro ships under
		// the RedisCachePro namespace.
		$impl = isset( $GLOBALS['wp_object_cache'] ) ? get_class( $GLOBALS['wp_object_cache'] ) : '';

		if ( false !== stripos( $impl, 'RedisCachePro' ) || class_exists( '\\RedisCachePro\\Plugin' ) ) {
			return 'Object Cache Pro';
		}
		if ( false !== stripos( $impl, 'Redis' ) ) {
			return 'Redis Object Cache';
		}
		if ( false !== stripos( $impl, 'Memcache' ) ) {
			return 'Memcached';
		}
		if ( false !== stripos( $impl, 'APCu' ) || false !== stripos( $impl, 'APC' ) ) {
			return 'APCu';
		}

		return __( 'External object cache', 'basecloud-boost' );
	}
}
