<?php
namespace ccxt;

// ----------------------------------------------------------------------------

// PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN:
// https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code

// -----------------------------------------------------------------------------
use React\Async;
use React\Promise;
include_once PATH_TO_CCXT . '/test/exchange/base/test_shared_methods.php';

function test_proxies($exchange, $skipped_properties) {
    return Async\async(function () use ($exchange, $skipped_properties) {
        Async\await(test_proxy_url($exchange, $skipped_properties));
        Async\await(test_http_proxy($exchange, $skipped_properties));
        // 'httpsProxy', 'socksProxy'
        Async\await(test_proxy_for_exceptions($exchange, $skipped_properties));
    }) ();
}


function test_proxy_url($exchange, $skipped_properties) {
    return Async\async(function () use ($exchange, $skipped_properties) {
        $method = 'proxyUrl';
        $proxy_server_ip = '5.75.153.75';
        [$proxy_url, $http_proxy, $https_proxy, $socks_proxy] = remove_proxy_options($exchange, $skipped_properties);
        $exchange->proxy_url = 'http://' . $proxy_server_ip . ':8090/proxy_url.php?caller=https://ccxt.com&url=';
        $encoded_colon = '%3A';
        $encoded_slash = '%2F';
        $ip_check_url = 'https' . $encoded_colon . $encoded_slash . $encoded_slash . 'api.ipify.org';
        $response = Async\await($exchange->fetch($ip_check_url));
        assert($response === $proxy_server_ip, $exchange->id . ' ' . $method . ' test failed. Returned response is ' . $response . ' while it should be "' . $proxy_server_ip . '"');
        // reset the instance property
        set_proxy_options($exchange, $skipped_properties, $proxy_url, $http_proxy, $https_proxy, $socks_proxy);
        return true;
    }) ();
}


function test_http_proxy($exchange, $skipped_properties) {
    return Async\async(function () use ($exchange, $skipped_properties) {
        $method = 'httpProxy';
        $proxy_server_ip = '5.75.153.75';
        [$proxy_url, $http_proxy, $https_proxy, $socks_proxy] = remove_proxy_options($exchange, $skipped_properties);
        $exchange->http_proxy = 'http://' . $proxy_server_ip . ':8911';
        $ip_check_url = 'https://api.ipify.org/';
        $response = Async\await($exchange->fetch($ip_check_url));
        assert($response === $proxy_server_ip, $exchange->id . ' ' . $method . ' test failed. Returned response is ' . $response . ' while it should be "' . $proxy_server_ip . '"');
        // reset the instance property
        set_proxy_options($exchange, $skipped_properties, $proxy_url, $http_proxy, $https_proxy, $socks_proxy);
    }) ();
}


// with the below method we test out all variations of possible proxy options, so at least 2 of them should be set together, and such cases must throw exception
function test_proxy_for_exceptions($exchange, $skipped_properties) {
    return Async\async(function () use ($exchange, $skipped_properties) {
        $method = 'testProxyForExceptions';
        [$proxy_url, $http_proxy, $https_proxy, $socks_proxy] = remove_proxy_options($exchange, $skipped_properties);
        $possible_options_array = ['proxyUrl', 'proxyUrlCallback', 'proxy_url', 'proxy_url_callback', 'httpProxy', 'httpProxyCallback', 'http_proxy', 'http_proxy_callback', 'httpsProxy', 'httpsProxyCallback', 'https_proxy', 'https_proxy_callback', 'socksProxy', 'socksProxyCallback', 'socks_proxy', 'socks_proxy_callback'];
        for ($i = 0; $i < count($possible_options_array); $i++) {
            for ($j = 0; $j < count($possible_options_array); $j++) {
                if ($j !== $i) {
                    $proxy_first = $possible_options_array[$i];
                    $proxy_second = $possible_options_array[$j];
                    $exchange->set_property($exchange, $proxy_first, '0.0.0.0'); // actual value does not matter
                    $exchange->set_property($exchange, $proxy_second, '0.0.0.0'); // actual value does not matter
                    $exception_caught = false;
                    try {
                        Async\await($exchange->fetch('http://example.com')); // url does not matter, it will not be called
                    } catch(\Throwable $e) {
                        $exception_caught = true;
                    }
                    assert($exception_caught, $exchange->id . ' ' . $method . ' test failed. No exception was thrown, while ' . $proxy_first . ' and ' . $proxy_second . ' were set together');
                    // reset to undefined
                    $exchange->set_property($exchange, $proxy_first, null);
                    $exchange->set_property($exchange, $proxy_second, null);
                }
            }
        }
        // reset the instance property
        set_proxy_options($exchange, $skipped_properties, $proxy_url, $http_proxy, $https_proxy, $socks_proxy);
    }) ();
}
