using CryptoExchange.Net.Objects;
using System;
using System.Collections.Generic;
using System.Data.Common;
using System.Linq;
namespace CryptoExchange.Net.SharedApis
{
///
/// Exchange parameters
///
public class ExchangeParameters
{
private readonly static Dictionary _staticProcessParameters = new Dictionary();
private readonly Dictionary _processParameters;
///
/// Create a new ExchangeParameters instance with the provided parameters set
///
/// Exchange parameters
public ExchangeParameters(params ExchangeParameter[] parameters)
{
_processParameters = new Dictionary();
foreach (var parameter in parameters)
AddValue(parameter.Exchange, parameter.Name, parameter.Value);
}
///
/// Add a process parameter. Process parameters are used to determine the correct logic to execute, but are not necessarily passed to the API.
/// To directly add or override parameters which are passed to the API, use AddRawParameter or AddRawValue instead.
///
/// The exchange parameter to add
public void AddValue(ExchangeParameter exchangeParameter)
{
AddValue(exchangeParameter.Exchange, exchangeParameter.Name, exchangeParameter.Value);
}
///
/// Add a process parameter. Process parameters are used to determine the correct logic to execute, but are not necessarily passed to the API.
/// To directly add or override parameters which are passed to the API, use AddRawParameter or AddRawValue instead.
///
/// Exchange to apply the parameter for
/// Parameter name
/// Parameter value
public void AddValue(string exchange, string key, object value)
{
if (!_processParameters.TryGetValue(exchange, out var exchangeParameters))
{
exchangeParameters = new Parameters(ParameterSerializationSettings.Default);
_processParameters[exchange] = exchangeParameters;
}
exchangeParameters.AddRaw(key, value);
}
///
/// Check whether a specific parameter is provided in this specific instance
///
/// The exchange name
/// Parameter name
/// Type of the parameter value
///
public bool HasValue(string exchange, string name, Type type)
{
var val = TryGetValue(_processParameters, exchange, name);
val ??= TryGetValue(_staticProcessParameters, exchange, name);
if (val == null)
return false;
try
{
Type t = Nullable.GetUnderlyingType(type) ?? type;
Convert.ChangeType(val, t);
return true;
}
catch
{
return false;
}
}
///
/// Check whether a specific process parameter is provided in the default parameters or the provided instance
///
/// The provided exchange parameter in the request
/// The exchange name
/// Parameter name
/// Type of the parameter value
///
public static bool HasValue(ExchangeParameters? exchangeParameters, string exchange, string name, Type type)
{
var provided = exchangeParameters?.HasValue(exchange, name, type);
if (provided == true)
return true;
var val = TryGetValue(_staticProcessParameters, exchange, name);
if (val == null)
return false;
try
{
Type t = Nullable.GetUnderlyingType(type) ?? type;
Convert.ChangeType(val, t);
return true;
}
catch
{
return false;
}
}
///
/// Get the value of a parameter from this instance
///
/// Type of the parameter value
/// Exchange name
/// Parameter name
public T? GetValue(string exchange, string name)
{
var val = TryGetValue(_processParameters, exchange, name);
val ??= TryGetValue(_staticProcessParameters, exchange, name);
if (val == null)
return default;
if (val is T typeVal)
return typeVal;
try
{
Type t = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);
return (T)Convert.ChangeType(val, t);
}
catch
{
throw new ArgumentException("Incorrect type for parameter, expected " + typeof(T).Name, name);
}
}
///
/// Get the value of a parameter from this instance or the default values
///
/// Type of the parameter value
/// The request parameters
/// Exchange name
/// Parameter name
public static T? GetValue(ExchangeParameters? exchangeParameters, string exchange, string name)
{
if (exchangeParameters != null) {
var provided = exchangeParameters.GetValue(exchange, name);
if (provided != null)
return provided;
}
var val = TryGetValue(_staticProcessParameters, exchange, name);
if (val == null)
return default;
try
{
var type = typeof(T);
Type t = Nullable.GetUnderlyingType(type) ?? type;
var result = Convert.ChangeType(val, t);
return (T)result;
}
catch
{
throw new ArgumentException("Incorrect type for parameter, expected " + typeof(T).Name, name);
}
}
///
/// Set static parameters
///
/// Exchange name
/// Parameter name
/// Parameter value
public static void SetStaticParameter(string exchange, string key, object value)
{
if (!_staticProcessParameters.TryGetValue(exchange, out var exchangeParameters))
{
exchangeParameters = new Parameters(ParameterSerializationSettings.Default);
_staticProcessParameters[exchange] = exchangeParameters;
}
exchangeParameters.Remove(key);
exchangeParameters.AddRaw(key, value);
}
///
/// Reset the static parameters, clears all parameters for all exchanges
///
public static void ResetStaticParameters()
{
_staticProcessParameters.Clear();
}
///
/// Reset the static parameters, clears all parameters for an exchange exchanges
///
public static void ResetStaticExchangeParameters(string exchange)
{
_staticProcessParameters.Remove(exchange);
}
private static object? TryGetValue(Dictionary list, string exchange, string key)
{
if (!list.TryGetValue(exchange, out var exchangeParams))
return null;
return exchangeParams.SingleOrDefault(x => x.Key.Equals(key, StringComparison.InvariantCultureIgnoreCase)).Value;
}
}
}