<?php
/**
 * Security and rate limiting configuration for Abandoned Cart Recovery.
 *
 * @package EDD\Pro\CartRecovery\Config
 * @copyright Copyright (c) 2026, Sandhills Development, LLC
 * @license https://opensource.org/licenses/GPL-2.0 GNU Public License
 * @since 3.6.5
 */

namespace EDD\Pro\CartRecovery\Config;

// Exit if accessed directly.
defined( 'ABSPATH' ) || exit; // @codeCoverageIgnore

/**
 * Security, rate limiting, and attack prevention configuration.
 */
final class Security {

	/**
	 * WordPress option key for storing ACR settings.
	 *
	 * @since 3.6.5
	 * @var string
	 */
	const OPTION_KEY = 'edd_acr_settings';

	/**
	 * Maximum cart items to prevent bloat.
	 *
	 * @since 3.6.5
	 * @var int
	 */
	const MAX_ITEMS_PER_CART = 50;

	/**
	 * Maximum JSON parsing depth to prevent attacks.
	 *
	 * @since 3.6.5
	 * @var int
	 */
	const MAX_JSON_DEPTH = 10;

	/**
	 * Maximum restore attempts per hour per IP (default).
	 *
	 * @since 3.6.5
	 * @var int
	 */
	const RESTORE_RATE_LIMIT = 5;

	/**
	 * Restore rate limit window in seconds (1 hour).
	 *
	 * @since 3.6.5
	 * @var int
	 */
	const RESTORE_RATE_WINDOW = HOUR_IN_SECONDS;

	/**
	 * Gets a security configuration value from storage.
	 *
	 * @since 3.6.5
	 * @param string $key Configuration key.
	 * @return mixed Configuration value or null if not found.
	 */
	private static function get( string $key ) {
		$options = get_option( self::OPTION_KEY, array() );

		return isset( $options[ $key ] ) ? $options[ $key ] : null;
	}

	/**
	 * Gets maximum items per cart.
	 *
	 * @since 3.6.5
	 * @return int Maximum items.
	 */
	public static function get_max_items_per_cart(): int {
		$value = (int) self::get( 'max_items_per_cart' );

		return $value > 0 ? $value : self::MAX_ITEMS_PER_CART;
	}

	/**
	 * Gets maximum JSON parsing depth.
	 *
	 * @since 3.6.5
	 * @return int Maximum depth.
	 */
	public static function get_max_json_depth(): int {
		$value = (int) self::get( 'max_json_depth' );

		return $value > 0 ? $value : self::MAX_JSON_DEPTH;
	}

	/**
	 * Gets restore rate limit per hour.
	 *
	 * @since 3.6.5
	 * @return int Maximum attempts.
	 */
	public static function get_restore_rate_limit(): int {
		$value = (int) self::get( 'restore_rate_limit' );

		return $value > 0 ? $value : self::RESTORE_RATE_LIMIT;
	}

	/**
	 * Gets restore rate window duration.
	 *
	 * @since 3.6.5
	 * @return int Window in seconds.
	 */
	public static function get_restore_rate_window(): int {
		$value = (int) self::get( 'restore_rate_window' );

		return $value > 0 ? $value : self::RESTORE_RATE_WINDOW;
	}
}
