<?php
/**
 * Request-Level Memoization Cache
 *
 * Stores computed values for the duration of a single request.
 * Does not persist across requests.
 *
 * @package SEOvaultSEO
 */

namespace SEOvaultSEO\Utils;

/**
 * Lightweight in-memory cache for request-level memoization.
 */
class RequestCache {

	/**
	 * Cached values keyed by deterministic string keys.
	 *
	 * @var array
	 */
	private static $cache = array();

	/**
	 * Get a cached value by key.
	 *
	 * @param string $key     Cache key.
	 * @param mixed  $default Default value if key is not found.
	 * @return mixed
	 */
	public static function get( $key, $default = null ) {
		if ( self::has( $key ) ) {
			return self::$cache[ $key ];
		}

		return $default;
	}

	/**
	 * Store a value in the cache.
	 *
	 * @param string $key   Cache key.
	 * @param mixed  $value Value to cache.
	 * @return void
	 */
	public static function set( $key, $value ) {
		self::$cache[ $key ] = $value;
	}

	/**
	 * Check whether a key exists in the cache.
	 *
	 * @param string $key Cache key.
	 * @return bool
	 */
	public static function has( $key ) {
		return array_key_exists( $key, self::$cache );
	}

	/**
	 * Remember a computed value: return cached result if available,
	 * otherwise execute the callback, cache the result, and return it.
	 *
	 * @param string   $key      Cache key.
	 * @param callable $callback Callback that produces the value.
	 * @return mixed
	 */
	public static function remember( $key, callable $callback ) {
		if ( self::has( $key ) ) {
			return self::$cache[ $key ];
		}

		$value               = $callback();
		self::$cache[ $key ] = $value;

		return $value;
	}

	/**
	 * Remove a single key from the cache.
	 *
	 * @param string $key Cache key.
	 * @return void
	 */
	public static function forget( $key ) {
		unset( self::$cache[ $key ] );
	}

	/**
	 * Reset the entire cache.
	 *
	 * @return void
	 */
	public static function reset() {
		self::$cache = array();
	}

	/**
	 * Get the number of items currently cached.
	 *
	 * @return int
	 */
	public static function count() {
		return count( self::$cache );
	}
}
