<?php
/**
 * HappyFenceNG Total Enterprise Security Plugin
 * HAPPYWPRESS is a RazorVue Trademark.
 *
 * @package     HappyFenceNG
 * @developer   Simonluca Scillitani
 * @copyright   2025 RazorVue di Scillitani Simonluca
 * @link        https://razorvue.it
 * @author      RazorVue di Scillitani Simonluca
 * @brand       HappyWPress
 * @uri         https://happywpress.com
 * @set all
 */

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

/**PHPCS -> code compliance: we put useful comments where needed.. */
class HappyFenceNGCFGuard extends HappyFenceNGService {


	/**PHPCS -> code compliance: we put useful comments where needed.. */
	public function init() {

		add_action( 'wp_head', array( $this, 'svc_block_request' ), HappyFenceNGStStored::FILTER_PRIORITY_CFGUARD );
		HappyFenceNGCStore::registerFunction( HappyFenceNGRgs::RFS_CRB, HappyFenceNGRgs::SR );
		add_action( 'wp_head', array( $this, 'svc_cf_detect' ), HappyFenceNGStStored::FILTER_PRIORITY_CFGUARD );
		HappyFenceNGCStore::registerFunction( HappyFenceNGRgs::RFS_CFD, HappyFenceNGRgs::SR );
	}

	/**PHPCS -> code compliance: we put useful comments where needed..
	 *
	 * @param string $method_name ... usually is self explained.
	 */
	public static function getStatus( string $method_name ) {
		switch ( $method_name ) {
			case 'svc_block_request':
				return HappyFenceNGCleaner::checkMe( HappyFenceNGWhoAmI::get_instance()->CF->enable_cf_guard, HappyFenceNGPlaceholder::BOOL_PROP_DEFAULT );
			case 'svc_cf_detect':
				return true;
			default:
				return HappyFenceNGPlaceholder::UNKNOWN;
		}
	}

	/**PHPCS -> code compliance: we put useful comments where needed.. */
	private function doBlock(): bool {
		if ( HappyFenceNGUtils::is_cloudflare_reversed() ) {
			$the_ip   = sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_CONNECTING_IP'] ?? '' ) );
			$flare_id = sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_RAY'] ?? '' ) );

			HappyFenceNGAlog::get_instance()->log(
				"OK CFGuard flare id $flare_id ip: $the_ip",
				HappyFenceNGSyslogFacility::SCANNER,
				HappyFenceNGSyslogSeverity::INFO
			);
			return true;
		}

		$remote_ip = '';

		if ( HappyFenceNGUtils::is_behind_proxy() ) {
			$remote_ip = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ?? '' ) ) );
		} else {
			$remote_ip = HappyFenceNGUtils::get_user_ip();
			// allow wp-cron do the job.
			$ip = HappyFenceNGUtils::get_user_ip();
			if ( HappyFenceNGPROC::equals( $ip, HappyFenceNGPlaceholder::WP_CRON ) ) {

				return true;
			}
		}

			$allowed = array_map( 'trim', explode( ',', HappyFenceNGCleaner::checkMe( HappyFenceNGWhoAmI::get_instance()->CF->allowed_ips, HappyFenceNGPlaceholder::EMPTY_STRING ) ) );
		foreach ( $allowed as $cidr ) {
			if ( $cidr && HappyFenceNGCleaner::ip_in_cidr( $remote_ip, $cidr ) ) {
				HappyFenceNGAlog::get_instance()->log(
					"CFGuard allowed IP access: $remote_ip",
					HappyFenceNGSyslogFacility::SCANNER,
					HappyFenceNGSyslogSeverity::INFO
				);
				return true;
			}
		}
				HappyFenceNGAlog::get_instance()->log(
					"CFGuard Blocked non-proxy IP access: $remote_ip",
					HappyFenceNGSyslogFacility::SECURITY,
					HappyFenceNGSyslogSeverity::WARNING
				);
				HappyFenceNGCleaner::cleaner_die(
					esc_html__( 'Nice try.', 'happyfenceng-total-enterprise-security' )
				);
	}

	/**PHPCS -> detects if requests come from CF and then raise a warning to the admin if the Guard is disabled */
	public function svc_cf_detect() {
		HappyFenceNGWhoAmI::get_instance()->EXECCHAIN::push_log( __FUNCTION__ );
		if ( ! HappyFenceNGCleaner::checkMe( HappyFenceNGWhoAmI::get_instance()->CF->enable_cf_guard, HappyFenceNGPlaceholder::BOOL_PROP_DEFAULT ) ) {
			if ( HappyFenceNGUtils::is_cloudflare_reversed() ) {
				$msg = 'Warning cloudflare detected, you should enable CFGuard to let HappyFenceNG work properly.';
				HappyFenceNGAlog::get_instance()->log(
					$msg,
					HappyFenceNGSyslogFacility::SCANNER,
					HappyFenceNGSyslogSeverity::ALERT
				);
				if ( is_admin() ) {
					set_transient( 'happyfenceng_cf_guard_detector', $msg, 14400 );
				}
			}
		} else {
			delete_transient( 'happyfenceng_cf_guard_detector' );
		}
		return true;
	}


	/**PHPCS -> code compliance: we put useful comments where needed.. */
	public function svc_block_request() {
		try {
			HappyFenceNGWhoAmI::get_instance()->EXECCHAIN::push_log( __FUNCTION__ );
			if ( HappyFenceNGCleaner::checkMe( HappyFenceNGWhoAmI::get_instance()->CF->enable_cf_guard, HappyFenceNGPlaceholder::BOOL_PROP_DEFAULT ) ) {
				if ( HappyFenceNGCleaner::checkMe( HappyFenceNGWhoAmI::get_instance()->CF->enable_cf_guard_admin_only, HappyFenceNGPlaceholder::BOOL_PROP_DEFAULT ) ) {
					if ( isset( $_SERVER['REQUEST_URI'] ) ) {
							$filtered     = wp_parse_url( sanitize_text_field( wp_unslash( $_SERVER['REQUEST_URI'] ?? HappyFenceNGPlaceholder::EMPTY_STRING ) ), PHP_URL_PATH );
							$request_path = ( $filtered ?? '/' );

						if ( str_contains( $request_path, 'wp-login.php' ) || str_contains( $request_path, 'admin.php' ) ) {
							self::doBlock();
						}
					}
				} else {
					self::doBlock();
				}
			}
		} catch ( Throwable $e ) {
			HappyFenceNGLOGCORE::logcore(
				'HappyFenceNG.CFS - scanner error ' . $e->getMessage(),
				HappyFenceNGSyslogFacility::SCANNER,
				HappyFenceNGSyslogSeverity::ERROR
			);
		}
	}
}
