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

// -----------------------------------------------------------------------------
include_once PATH_TO_CCXT . '/test/exchange/base/test_shared_methods.php';

function test_currency($exchange, $skipped_properties, $method, $entry) {
    $format = array(
        'id' => 'btc',
        'code' => 'BTC',
    );
    // todo: remove fee from empty
    $empty_allowed_for = ['name', 'fee'];
    // todo: info key needs to be added in base, when exchange does not have fetchCurrencies
    $is_native = $exchange->has['fetchCurrencies'] && $exchange->has['fetchCurrencies'] !== 'emulated';
    $currency_type = $exchange->safe_string($entry, 'type');
    if ($is_native) {
        $format['info'] = array();
        // todo: 'name': 'Bitcoin', // uppercase string, base currency, 2 or more letters
        $format['withdraw'] = true; // withdraw enabled
        $format['deposit'] = true; // deposit enabled
        $format['precision'] = $exchange->parse_number('0.0001'); // in case of SIGNIFICANT_DIGITS it will be 4 - number of digits "after the dot"
        $format['fee'] = $exchange->parse_number('0.001');
        $format['networks'] = array();
        $format['limits'] = array(
            'withdraw' => array(
                'min' => $exchange->parse_number('0.01'),
                'max' => $exchange->parse_number('1000'),
            ),
            'deposit' => array(
                'min' => $exchange->parse_number('0.01'),
                'max' => $exchange->parse_number('1000'),
            ),
        );
        $format['type'] = 'crypto'; // crypto, fiat, leverage, other
        assert_in_array($exchange, $skipped_properties, $method, $entry, 'type', ['fiat', 'crypto', 'leveraged', 'other', null]); // todo: remove undefined
        // only require "deposit" & "withdraw" values, when currency is not fiat, or when it's fiat, but not skipped
        if ($currency_type !== 'crypto' && (is_array($skipped_properties) && array_key_exists('depositForNonCrypto', $skipped_properties))) {
            $empty_allowed_for[] = 'deposit';
        }
        if ($currency_type !== 'crypto' && (is_array($skipped_properties) && array_key_exists('withdrawForNonCrypto', $skipped_properties))) {
            $empty_allowed_for[] = 'withdraw';
        }
        if ($currency_type === 'leveraged' || $currency_type === 'other') {
            $empty_allowed_for[] = 'precision';
        }
    }
    //
    assert_currency_code($exchange, $skipped_properties, $method, $entry, $entry['code']);
    // check if empty networks should be skipped
    $networks = $exchange->safe_dict($entry, 'networks', array());
    $network_keys = is_array($networks) ? array_keys($networks) : array();
    $network_keys_length = count($network_keys);
    if ($network_keys_length === 0 && (is_array($skipped_properties) && array_key_exists('skipCurrenciesWithoutNetworks', $skipped_properties))) {
        return;
    }
    //
    assert_structure($exchange, $skipped_properties, $method, $entry, $format, $empty_allowed_for);
    //
    check_precision_accuracy($exchange, $skipped_properties, $method, $entry, 'precision');
    assert_greater_or_equal($exchange, $skipped_properties, $method, $entry, 'fee', '0');
    if (!(is_array($skipped_properties) && array_key_exists('limits', $skipped_properties))) {
        $limits = $exchange->safe_value($entry, 'limits', array());
        $withdraw_limits = $exchange->safe_value($limits, 'withdraw', array());
        $deposit_limits = $exchange->safe_value($limits, 'deposit', array());
        assert_greater_or_equal($exchange, $skipped_properties, $method, $withdraw_limits, 'min', '0');
        assert_greater_or_equal($exchange, $skipped_properties, $method, $withdraw_limits, 'max', '0');
        assert_greater_or_equal($exchange, $skipped_properties, $method, $deposit_limits, 'min', '0');
        assert_greater_or_equal($exchange, $skipped_properties, $method, $deposit_limits, 'max', '0');
        // max should be more than min (withdrawal limits)
        $min_string_withdrawal = $exchange->safe_string($withdraw_limits, 'min');
        if ($min_string_withdrawal !== null) {
            assert_greater_or_equal($exchange, $skipped_properties, $method, $withdraw_limits, 'max', $min_string_withdrawal);
        }
        // max should be more than min (deposit limits)
        $min_string_deposit = $exchange->safe_string($deposit_limits, 'min');
        if ($min_string_deposit !== null) {
            assert_greater_or_equal($exchange, $skipped_properties, $method, $deposit_limits, 'max', $min_string_deposit);
        }
        // check valid ID & CODE
        assert_valid_currency_id_and_code($exchange, $skipped_properties, $method, $entry, $entry['id'], $entry['code']);
    }
}
