<?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.. */
final class HappyFenceNGUtils extends HappyFenceNGRuntimeExceptions {
    /**PHPCS -> code compliance: we put useful comments where needed.. */
    public static function getPageTitle() {
        $page_title = 'HappyFenceNG Total Security FREE';
        return $page_title;
    }

    /**PHPCS -> code compliance: we put useful comments where needed.. */
    public static function getMenuTitle() {
        $menu_title = 'HappyFenceNG FREE';
        return $menu_title;
    }

    /**PHPCS -> code compliance: we put useful comments where needed..
     *
     * @param int $length ... maybe it's the lenght.
     */
    public static function generateStrongPassword( $length = HappyFenceNGPcoreProps::_PWD_LEN ) {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789@#%^_-+=';
        $password = HappyFenceNGPlaceholder::EMPTY_STRING;
        $max_index = strlen( $chars ) - 1;
        for ($i = 0; $i < $length; $i++) {
            $password .= $chars[random_int( 0, $max_index )];
        }
        return $password;
    }

    /**PHPCS -> code compliance: we put useful comments where needed..
     *
     * @param int $length ... maybe it's the lenght.
     */
    public static function generateStrongSlug( $length = HappyFenceNGPcoreProps::_SLUG_LEN ) {
        $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
        $slug = HappyFenceNGPlaceholder::EMPTY_STRING;
        $max_index = strlen( $chars ) - 1;
        for ($i = 0; $i < $length; $i++) {
            $slug .= $chars[random_int( 0, $max_index )];
        }
        return $slug;
    }

    /**PHPCS -> code compliance: we put useful comments where needed..
     *
     * @param string $ip .. the ip?.
     * @param string $ua .. no it's not some woodoo ... it's the user agent.
     * @param string $time ... time is never enought you know.
     */
    public static function generateToken( $ip, $ua, $time ) {
        return self::enc( maybe_serialize( array(
            'IP'    => $ip,
            'UA'    => $ua,
            'TIME'  => $time,
            'VSLUG' => self::generateStrongSlug( HappyFenceNGPcoreProps::_SLUG_LEN ),
        ) ) );
    }

    /**PHPCS -> code compliance: we put useful comments where needed..
     *
     * @param string $encrypted .. to be honest don't know what it is, maybe reading the code could help.
     */
    public static function getToken( $encrypted ) {
        return maybe_unserialize( self::dec( $encrypted ) );
    }

    /**PHPCS -> code compliance: we put useful comments where needed..
     *
     * @param string $value ..a value?.
     */
    private static function enc( $value ) : ?string {
        try {
            if ( HappyFenceNGPROC::equals( $value, null ) ) {
                $value = new HappyFenceNGPlaceholder();
            }
            $key = HappyFence2KeyManager::get_instance()->get_key();
            //phpcs:ignore
            return base64_encode( openssl_encrypt(
                //phpcs:ignore we know what we do!
                maybe_serialize( $value ),
                'aes-256-cbc',
                $key,
                0,
                substr( $key, 0, 16 )
            ) );
        } catch ( \Throwable $e ) {
            HappyFenceNGLOGCORE::logcore( self::class . 'ZTV::MOV->' . $e->getMessage(), HappyFenceNGSyslogFacility::ZTV, HappyFenceNGSyslogSeverity::CRITICAL );
            return HappyFenceNGPlaceholder::EMPTY_STRING;
        }
    }

    /**PHPCS -> code compliance: we put useful comments where needed..
     *
     * @param string $payload .. a payload?.
     */
    private static function dec( $payload ) {
        try {
            if ( HappyFenceNGPROC::equals( $payload, null ) ) {
                return HappyFenceNGPlaceholder::EMPTY_STRING;
            }
            $key = HappyFence2KeyManager::get_instance()->get_key();
            $decrypted = openssl_decrypt(
                //phpcs:ignore
                base64_decode( $payload ),
                'aes-256-cbc',
                $key,
                0,
                substr( $key, 0, 16 )
            );
            if ( HappyFenceNGPROC::not_equals( $decrypted, false ) ) {
                //phpcs:ignore we know what we do!
                $tmp_dec = maybe_unserialize( $decrypted );
                if ( $tmp_dec instanceof HappyFenceNGPlaceholder ) {
                    return HappyFenceNGPlaceholder::EMPTY_STRING;
                } else {
                    return $tmp_dec;
                }
            } else {
                return HappyFenceNGPlaceholder::EMPTY_STRING;
            }
        } catch ( \Throwable $e ) {
            HappyFenceNGLOGCORE::logcore( self::class . 'ZTV::EXP->' . $e->getMessage(), HappyFenceNGSyslogFacility::ZTV, HappyFenceNGSyslogSeverity::CRITICAL );
        }
    }

    /**PHPCS -> code compliance: we put useful comments where needed.. */
    public static function is_cloudflare_reversed() : bool {
        return !empty( $_SERVER['HTTP_CF_RAY'] ) && !empty( $_COOKIE['cf_clearance'] );
    }

    /**PHPCS -> code compliance: we put useful comments where needed.. */
    public static function is_behind_proxy() : bool {
        $is_reversed = false;
        if ( !empty( $_SERVER['HTTP_X_REAL_IP'] ) && !empty( $_SERVER['REMOTE_ADDR'] ) ) {
            $the_real_ip = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) ) );
            $the_remote_address = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) );
            $is_reversed = HappyFenceNGPROC::not_equals( $the_real_ip, $the_remote_address );
        }
        return $is_reversed;
    }

    /**PHPCS -> code compliance: we put useful comments where needed.. */
    public static function get_reverse_proxy_ip() {
        return HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ?? '' ) ) );
    }

    /**PHPCS -> code compliance: we put useful comments where needed.. */
    public static function get_ips() : array {
        $ips = array();
        if ( !empty( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ) {
            $ips[] = sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_CONNECTING_IP'] ) );
        }
        if ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
            // Ottieni il primo IP valido dalla lista separata da virgole.
            $ips = explode( ',', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ?? '' ) ) );
            foreach ( $ips as $ip ) {
                $ip = trim( $ip );
                // Rimuove eventuali spazi extra.
                // Verifica se l'IP è valido.
                if ( HappyFenceNGCleaner::must_be_ip( $ip ) ) {
                    $ips[] = $ip;
                }
            }
        }
        if ( !empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
            $ips[] = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ) ) );
        }
        if ( !empty( $_SERVER['HTTP_X_REAL_IP'] ) ) {
            $ips[] = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) ) );
        }
        if ( !empty( $_SERVER['HTTP_X_FORWARDED'] ) ) {
            $ips[] = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED'] ) ) );
        }
        if ( !empty( $_SERVER['REMOTE_ADDR'] ) ) {
            $ips[] = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) );
        }
        if ( !empty( $_SERVER['REMOTE_HOST'] ) ) {
            $ips[] = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['REMOTE_HOST'] ) ) );
        }
        return $ips;
    }

    /**PHPCS -> code compliance: we put useful comments where needed.. */
    public static function get_user_ip() {
        $script_name = sanitize_text_field( wp_unslash( $_SERVER['SCRIPT_NAME'] ?? '' ) );
        if ( HappyFenceNGPROC::not_equals( stripos( $script_name, 'wp-cron.php' ), false ) ) {
            HappyFenceNGAlog::get_instance()->log( 'HappyFenceNG.GET USE IP - it seems that cron called me:' . wp_json_encode( $_SERVER ), HappyFenceNGSyslogFacility::SECURITY, HappyFenceNGSyslogSeverity::DEBUG );
            return HappyFenceNGPlaceholder::WP_CRON;
        } else {
            $the_ip = HappyFenceNGPlaceholder::EMPTY_STRING;
            if ( !empty( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ) {
                $the_ip = sanitize_text_field( wp_unslash( $_SERVER['HTTP_CF_CONNECTING_IP'] ) );
            } elseif ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
                // Ottieni il primo IP valido dalla lista separata da virgole.
                $ips = explode( ',', sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED_FOR'] ?? '' ) ) );
                foreach ( $ips as $ip ) {
                    $ip = trim( $ip );
                    // Rimuove eventuali spazi extra.
                    // Verifica se l'IP è valido.
                    if ( HappyFenceNGCleaner::must_be_ip( $ip ) ) {
                        $the_ip = $ip;
                        break;
                        // Usa il primo IP valido trovato.
                    }
                }
                HappyFenceNGAlog::get_instance()->log( 'HappyFenceNG.GET USER IP - X FORWARDERS. Params:' . wp_json_encode( $ips ) . " we use {$the_ip}", HappyFenceNGSyslogFacility::SECURITY, HappyFenceNGSyslogSeverity::AUDIT );
            } elseif ( !empty( $_SERVER['HTTP_CLIENT_IP'] ) ) {
                $the_ip = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['HTTP_CLIENT_IP'] ) ) );
            } elseif ( !empty( $_SERVER['HTTP_X_REAL_IP'] ) ) {
                $the_ip = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_REAL_IP'] ) ) );
            } elseif ( !empty( $_SERVER['HTTP_X_FORWARDED'] ) ) {
                $the_ip = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['HTTP_X_FORWARDED'] ) ) );
            } elseif ( !empty( $_SERVER['REMOTE_ADDR'] ) ) {
                $the_ip = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) );
            } elseif ( !empty( $_SERVER['REMOTE_HOST'] ) ) {
                $the_ip = HappyFenceNGCleaner::must_be_ip( sanitize_text_field( wp_unslash( $_SERVER['REMOTE_HOST'] ) ) );
            } else {
                HappyFenceNGAlog::get_instance()->log( 'HappyFenceNG.GET USER IP - cannot determine ip address. Params:' . wp_json_encode( $_SERVER ), HappyFenceNGSyslogFacility::SECURITY, HappyFenceNGSyslogSeverity::WARNING );
                $the_ip = HappyFenceNGPlaceholder::EMPTY_STRING;
            }
            if ( HappyFenceNGPROC::equals( $the_ip, HappyFenceNGPlaceholder::NOT_A_VALID_IP ) ) {
                $the_ip = HappyFenceNGPlaceholder::EMPTY_STRING;
            }
        }
        return $the_ip;
    }

    /**PHPCS -> code compliance: we put useful comments where needed.. */
    public static function get_patch() {
        return HappyFenceNGPlaceholder::EMPTY_STRING;
    }

}
