<?php

/**
 * Curl http request.
 */

namespace EnEchoCurl;

/**
 * Generic http request.
 * Class EnEchoCurl
 * @package EnEchoCurl
 */
if (!class_exists('EnEchoCurl')) {

    class EnEchoCurl
    {
        /**
         * @param string $url
         * @param array $post_data
         * @param string $method
         * @param string string $step_for
         * @return string|encoded
         */
        static public function en_echo_sent_http_request($url, $post_data, $method, $step_for = '')
        {
            $curl_response = '';
            $en_time_start = 0;

            if (strlen($url) > 0 && is_array($post_data) && !empty($post_data)) {

                $post_data = self::remove_extra_request_data($post_data);
                $cachable_data = self::create_cachable_data($post_data);
                $cache_key = self::create_cache_key($cachable_data);
                $cache_response = get_transient($cache_key);
                $skip_cache = in_array($step_for, ['Plan', 'Logs', 'Address', 'Connection']);

                if (false === $cache_response || $skip_cache) {
                    // Eniture Execution Time
                    $en_time_start = microtime(true);

                    // Eniture Debug Mood
                    do_action("eniture_debug_mood", EN_ECHO_NAME . " $step_for Request ", $post_data);

                    $method == 'POST' ? $post_data = http_build_query($post_data) : '';

                    // Eniture Debug Mood
                    do_action("eniture_debug_mood", EN_ECHO_NAME . " $step_for Build Query ", $post_data);

                    $response = wp_remote_post($url, [
                            'method' => $method,
                            'timeout' => 60,
                            'redirection' => 5,
                            'blocking' => true,
                            'body' => $post_data,
                        ]
                    );
                    $headers = wp_remote_retrieve_headers($response);
                    self::eniture_check_rate_limit_headers($headers);
                    $curl_response = wp_remote_retrieve_body($response);
                    $resp = !empty($curl_response) && is_string($curl_response) ? json_decode($curl_response, true) : $curl_response;

                    if (!empty($resp) && (!isset($resp['severity']) || (isset($resp['severity']) && $resp['severity'] != 'ERROR'))) {
                        set_transient($cache_key, $curl_response, 12 * HOUR_IN_SECONDS);
                    }

                    // Eniture Debug Mood
                    do_action("eniture_debug_mood", EN_ECHO_NAME . " $step_for Response ", json_decode($curl_response));
                } else {
                    $curl_response = $cache_response;
                    // Eniture Debug Mood
                    do_action("eniture_debug_mood", EN_ECHO_NAME . " $step_for Cache Response ", $curl_response);
                }
            }

            // Eniture Execution Time
            $en_time_end = microtime(true) - $en_time_start;
            do_action("eniture_debug_mood", EN_ECHO_NAME . " $step_for Execution Time ", $en_time_end);

            return $curl_response;
        }

        static public function eniture_check_rate_limit_headers($headers)
        {
            $rate_limit_flag = isset($headers['X-RateLimit-Flag']) ? filter_var($headers['X-RateLimit-Flag'], FILTER_VALIDATE_BOOLEAN) : false;

            if ($rate_limit_flag) {
                if (isset($headers['X-RateLimit-Reset'])) {
                    update_option('eniture_show_rate_limit_notice_with_time', 'yes');
                    update_option('eniture_rate_limit_reset_timestamp', $headers['X-RateLimit-Reset']);
                } else {
                    update_option('eniture_show_rate_limit_notice_without_time', 'yes');
                }
            } else {
                update_option('eniture_show_rate_limit_notice_with_time', 'no');
                update_option('eniture_show_rate_limit_notice_without_time', 'no');
            }
        }

        static public function remove_extra_request_data($request_data)
        {
            $extra_params = ['en_fdo_meta_data'];
            foreach ($extra_params as $param) {
                if (!isset($request_data[$param])) continue;

                $items = isset($request_data[$param]['items']) ? $request_data[$param]['items'] : [];
                foreach ($items as $key => $item) {
                    unset($items[$key]['attributes'], $items[$key]['meta_data']);
                }

                $request_data[$param]['items'] = $items;
                break;
            }

            return $request_data;
        }

        static public function create_cachable_data($request_data)
        {
            $cache_keys = ['serverName', 'platform', 'carrierType', 'carrierName', 'carrierMode', 'requestVersion', 'apiKey', 'accountNumber', 'licenseKey', 'shipment_type', 'LTL_FREIGHT', 'product_name', 'shipment_weight', 'commdityDetails', 'originAddress', 'receiverZip', 'receiverState', 'receiverCountryCode', 'receiverCity', 'instorPickupLocalDelEnable', 'doNesting', 'accessorials', 'handlingUnitWeight', 'maxWeightPerHandlingUnit', 'holdAtTerminal', 'shipmentOffsetDays', 'OrderCutoffTime', 'shipmentWeekDays', 'modifyShipmentDateTime'];
            $cachable_data = [];
            
            // get the data from the request
            foreach ($cache_keys as $key) {
                if (isset($request_data[$key])) $cachable_data[$key] = $request_data[$key];
            }

            if (isset($request_data['autoResidentials']) && $request_data['autoResidentials'] == 1) {
                $cachable_data['autoResidentials'] = $request_data['autoResidentials'];
                $cachable_data['addressLine'] = $request_data['addressLine'];
                $cachable_data['addressLine2'] = (isset($request_data['addressLine2'])) ? $request_data['addressLine2'] : '';
                $cachable_data['defaultRADAddressType'] = $request_data['defaultRADAddressType'];
                $cachable_data['defaultRADWithoutStreetAddress'] = $request_data['defaultRADWithoutStreetAddress'];
                $cachable_data['poboxAddressValidation'] = $request_data['poboxAddressValidation'];
            }

            if (isset($request_data['standardPackaging']) && $request_data['standardPackaging'] == 1) {
                $cachable_data['standardPackaging'] = $request_data['standardPackaging'];
                $cachable_data['pallet'] = $request_data['pallet'];
            }

            return $cachable_data;
        }

        static public function create_cache_key($request_data)
        {
            $request_build_query = http_build_query($request_data);
            return md5('eniture_echo_' . $request_build_query);
        }
    }

}