<?php

 /**
 * =============================================================================
 * @package         Blue Raven (Free Version)
 * @Plugin URI      https://enterrahost.com/plugins/blue-raven
 * 
 * @Author          EnterraHost
 * @Author URI      https://enterrahost.com
 * @License         GPL-2.0-or-later
 *  
 * @Copyright       (c) 2025 EnterraHost
 * @Contents        Validate the user submitted license 
 * 
 * =============================================================================
 * 
 * || INDEX:
 * ||   -  HANDLE VALIDATE LICENSE 
 * ||   -  FETCH REMOTE KEY
 * ||   -  FETCH ENTERRA PASS
 * || 
 * =============================================================================
 */
 
if ( ! defined( 'ABSPATH' ) ) exit; 

/*
============================================================
    HANDLE VALIDATE LICENSE 
============================================================
*/ 

function blue_raven_handle_validate_license($license_key) {
   
    ## =========== Configuration =========== ##
    
    $whmcs_url = 'https://portal.enterrahost.com/modules/servers/licensing/verify.php';
    $key_endpoint = 'https://portal.enterrahost.com/keys/blue-raven-key.php';
    $getPass = 'https://portal.enterrahost.com/get-pass.php';

    $domain = isset($_POST['domain']) ? sanitize_text_field(wp_unslash($_POST['domain'])) : (isset($_SERVER['SERVER_NAME']) ? sanitize_text_field(wp_unslash($_SERVER['SERVER_NAME'])) : '');

    
    try {

        ###-- Fetch the secret key 

        $licensing_secret_key = fetchRemoteKey($key_endpoint);
        
        ###-- Fetch Pass (with error handling)

        $licensing_pass = '';
        $enterraID = 0;
        
        try {
            $enterra_verify = fetchEnterraPass($getPass, $license_key);
            $licensing_pass = $enterra_verify['code'];
            $enterraID = $enterra_verify['userid'];
        
        } catch (Exception $e) {
            SendError("ERROR", "class-blue-raven-license-handler.php", "get-pass fails", "get-pass - enterra_verify failed to get");
        }
        
        ###-- Generate unique check token

        $check_token = time() . md5(wp_rand(100000000, mt_getrandmax()) . $license_key);
        
        ###-- Build POST data

        $post_fields = ['licensekey' => $license_key, 'domain' => $domain, 'ip' => isset($_SERVER['SERVER_ADDR']) ? sanitize_text_field(wp_unslash($_SERVER['SERVER_ADDR'])) : '127.0.0.1', 'dir' => __DIR__, 'check_token' => $check_token];

    ## ===========  Send validation request =========== ##
    
		$response = wp_remote_post($whmcs_url, [
			'body'    => $post_fields,
			'timeout' => 30,
			'sslverify' => true,
		]);

		$http_code = wp_remote_retrieve_response_code($response);
		$body      = wp_remote_retrieve_body($response);

		$results = [];

		if (!is_wp_error($response) && $http_code === 200) {
            preg_match_all('/<(.*?)>([^<]+)<\/\\1>/', $body, $matches);
            
            foreach ($matches[1] as $index => $key) {$results[$key] = $matches[2][$index];}
            
            ### --  Validate MD5 hash

            if (isset($results['md5hash'])) {
                $expected_hash = md5($licensing_secret_key . $check_token);
                if ($results['md5hash'] !== $expected_hash) {
                    $results['status'] = 'Invalid';
                    $results['error'] = 'Hash verification failed';
                    $results['debug_info'] = ['expected' => $expected_hash,'received' => $results['md5hash'],'key_used' => $licensing_secret_key];
                }
            }
            
    ## ===========  Update tables =========== ##
    
            if($results['status'] == 'Active'){
                global $wpdb;
                
                $updates = ['licensed' => 'yes','licenseKey' => $license_key,'enterra_user' => $results['registeredname']];
                
                ###-- Only add these if we successfully got them from get-pass.php

                if (!empty($licensing_pass)) $updates['licensepass'] = $licensing_pass;
                if (!empty($enterraID)) $updates['enterra_id'] = $enterraID;
                
                foreach ($updates as $setting => $value) {$wpdb->replace($wpdb->prefix . 'BlueRavenConfig',['setting' => $setting,'value' => $value],['%s', '%s']);}
                
            } else {
                wp_send_json_error("ISSUE " . print_r($results, true));
            }
        } else {
			
    ## =========== Proper error handling =========== ##
			
			$results['error'] = is_wp_error($response)
				? $response->get_error_message()
				: "Connection failed (HTTP $http_code)";
			wp_send_json_error($results);
        }
    } catch (Exception $e) {
        wp_send_json_error('Error : Something Went wrong, Contact Support' .  $e->getMessage());
        SendError("ERROR", "class-blue-raven-license-handler.php", "blue_raven_handle_validate_license Catch", $e->getMessage());
    }
    
    wp_send_json_success('License validated successfully!');
}

/*
============================================================
    FETCH REMOTE KEY
============================================================
*/ 
 
function fetchRemoteKey($endpoint) {
    $response = wp_remote_get($endpoint, [
        'timeout'   => 5,
        'sslverify' => true,
        'redirection' => 0, 
    ]);

    if (is_wp_error($response)) {
        throw new Exception(esc_html('Failed to fetch key: ' . $response->get_error_message()));
    }

    $http_code = wp_remote_retrieve_response_code($response);

    if ($http_code !== 200) {
        throw new Exception(esc_html(sprintf('Failed to fetch key (HTTP %d)', $http_code)));
    }

    $body = wp_remote_retrieve_body($response);
    return trim($body);
}
 
/*
============================================================
    FETCH ENTERRA PASS
============================================================
*/ 

function fetchEnterraPass($endpoint, $license_key) {
    $url = add_query_arg('license_key', rawurlencode($license_key), $endpoint);

    $response = wp_remote_get($url, [
        'timeout'     => 10,
        'redirection' => 3,
        'headers'     => [
            'Accept'       => 'application/json',
            'Content-Type' => 'application/json',
        ],
    ]);

    if (is_wp_error($response)) {
        throw new RuntimeException(esc_html('Request error: ' . $response->get_error_message()));
    }

    $http_code = wp_remote_retrieve_response_code($response);
    if ($http_code === 404) {
        throw new Exception(esc_html('get-pass endpoint not found'));
    } elseif ($http_code !== 200) {
        throw new RuntimeException(esc_html('API request failed with HTTP code: ' . $http_code));
    }

    $body = wp_remote_retrieve_body($response);
    $data = json_decode($body, true);
    if (json_last_error() !== JSON_ERROR_NONE) {
        throw new RuntimeException(esc_html('Failed to decode JSON: ' . json_last_error_msg()));
    }

    $requiredFields = ['code', 'userid'];
    foreach ($requiredFields as $field) {
        if (!array_key_exists($field, $data)) throw new RuntimeException(esc_html("Missing required field in response: $field"));
    }

    return [
        'code'   => trim($data['code']),
        'userid' => (int) $data['userid'],
    ];
}