<?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

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


function test_features($exchange, $skipped_properties) {
    $market_types = ['spot', 'swap', 'future', 'option'];
    $sub_types = ['linear', 'inverse'];
    $features = $exchange->features;
    $keys = is_array($features) ? array_keys($features) : array();
    for ($i = 0; $i < count($keys); $i++) {
        assert_in_array($exchange, $skipped_properties, 'features', $keys, $i, $market_types);
        $market_type = $keys[$i];
        $value = $features[$market_type];
        // assert (value !== undefined, 'exchange.features["' + marketType + '"] is undefined, that key should be either absent or have a value');
        if ($value === null) {
            continue;
        }
        if ($market_type === 'spot') {
            test_features_inner($exchange, $skipped_properties, $value);
        } else {
            $sub_keys = is_array($value) ? array_keys($value) : array();
            for ($j = 0; $j < count($sub_keys); $j++) {
                $sub_key = $sub_keys[$j];
                assert_in_array($exchange, $skipped_properties, 'features', $sub_keys, $j, $sub_types);
                $sub_value = $value[$sub_key];
                // sometimes it might not be available for exchange, eg. future>inverse)
                if ($sub_value !== null) {
                    test_features_inner($exchange, $skipped_properties, $sub_value);
                }
            }
        }
    }
    return true;
}


function test_features_inner($exchange, $skipped_properties, $feature_obj) {
    $format = array(
        'sandbox' => false,
        'createOrder' => array(
            'marginMode' => false,
            'triggerPrice' => false,
            'triggerPriceType' => array(
                'mark' => false,
                'last' => false,
                'index' => false,
            ),
            'stopLossPrice' => false,
            'takeProfitPrice' => false,
            'attachedStopLossTakeProfit' => array(
                'triggerPriceType' => array(
                    'last' => false,
                    'mark' => false,
                    'index' => false,
                ),
                'price' => false,
            ),
            'timeInForce' => array(
                'GTC' => false,
                'IOC' => false,
                'FOK' => false,
                'PO' => false,
                'GTD' => false,
            ),
            'hedged' => false,
            'trailing' => false,
        ),
        'createOrders' => array(
            'max' => 5,
        ),
        'fetchMyTrades' => array(
            'marginMode' => false,
            'daysBack' => 0,
            'limit' => 0,
            'untilDays' => 0,
            'symbolRequired' => false,
        ),
        'fetchOrder' => array(
            'marginMode' => false,
            'trigger' => false,
            'trailing' => false,
            'symbolRequired' => false,
        ),
        'fetchOpenOrders' => array(
            'marginMode' => false,
            'limit' => 0,
            'trigger' => false,
            'trailing' => false,
            'symbolRequired' => false,
        ),
        'fetchOrders' => array(
            'marginMode' => false,
            'limit' => 0,
            'daysBack' => 0,
            'untilDays' => 0,
            'trigger' => false,
            'trailing' => false,
            'symbolRequired' => false,
        ),
        'fetchClosedOrders' => array(
            'marginMode' => false,
            'limit' => 0,
            'daysBack' => 0,
            'daysBackCanceled' => 0,
            'untilDays' => 0,
            'trigger' => false,
            'trailing' => false,
            'symbolRequired' => false,
        ),
        'fetchOHLCV' => array(
            'limit' => 0,
        ),
    );
    $feature_keys = is_array($feature_obj) ? array_keys($feature_obj) : array();
    $all_methods = is_array($exchange->has) ? array_keys($exchange->has) : array();
    for ($i = 0; $i < count($feature_keys); $i++) {
        assert_in_array($exchange, $skipped_properties, 'features', $feature_keys, $i, $all_methods);
        assert_structure($exchange, $skipped_properties, 'features', $feature_obj, $format, null, true); // deep structure check
    }
}
