<?php
/**
 * Shared Captcha Skip Rules
 *
 * Roadmap item #28: role-based + IP-based skip rules. Centralised so every
 * captcha module applies the same semantics; modules opt in by calling
 * {@see self::shouldSkip()} at the very top of their verify path.
 *
 * Skip is additive: a request is skipped if ANY of the enabled rules match.
 * Loggedoff/anonymous users never short-circuit via role rules (they have no
 * roles) — only IP allowlist can skip them.
 *
 * The helper is intentionally inert until a captcha module calls it, so it
 * adds zero load when all captcha modules are disabled.
 *
 * @package WP_PowerSuite\Captcha\Shared
 * @since 1.1.0
 */

namespace WP_PowerSuite\Captcha\Shared;

/**
 * Skip rule evaluator.
 *
 * Options shape (inside each module's `skip_rules` array):
 *   [
 *     'enabled'    => bool,
 *     'roles'       => array<string> (role slugs, e.g. ['administrator','editor'])
 *     'ips'         => array<string> (IPs or CIDR)
 *     'user_agents' => array<string> (substring match against HTTP_USER_AGENT)
 *   ]
 */
final class SkipRules {

	/**
	 * Evaluate skip rules for the current request.
	 *
	 * @param array<string,mixed> $rules  Skip rule settings for this module.
	 * @return bool True when the captcha challenge should be bypassed.
	 */
	public static function shouldSkip( array $rules ): bool {
		if ( class_exists( PremiumSkipRules::class, false ) ) {
			return PremiumSkipRules::shouldSkip( $rules );
		}

		return false;
	}

	/**
	 * Normalise an admin-supplied newline-separated list into a clean array.
	 *
	 * @param string $raw  Raw textarea contents.
	 * @return array<string>
	 */
	public static function parseList( string $raw ): array {
		$lines = preg_split( '/\r\n|\r|\n/', $raw );
		if ( ! is_array( $lines ) ) {
			return [];
		}
		$out = [];
		foreach ( $lines as $line ) {
			$line = trim( (string) $line );
			if ( $line !== '' ) {
				$out[] = $line;
			}
		}
		return $out;
	}
}
