pub enum API {
  SpotV3(SpotV3),
  Savings(Savings),
  Futures(Futures),
  AccountGeneral(AccountGeneral),
}

/// Endpoint for production and test orders.
///
/// Orders issued to test are validated, but not sent into the matching engine.
pub enum SpotV3 {
  Ping,
  Time,
  ExchangeInfo,
  Depth,
  Trades,
  HistoricalTrades,
  AggTrades,
  Klines,
  AvgPrice,
  Ticker24hr,
  Price,
  BookTicker,
  Order,
  OrderTest,
  OpenOrders,
  AllOrders,
  Oco,
  OrderList,
  AllOrderList,
  OpenOrderList,
  Account,
  MyTrades,
  RateLimitOrder,
  MyPreventedMatches,
  MyAllocations,
  AccountCommissions,
  UserDataStream,
}

pub enum Savings {
  AllCoins,
  AssetDetail,
  DepositAddress,
  SpotFuturesTransfer,
}

pub enum Futures {
  Ping,
  Time,
  ExchangeInfo,
  Depth,
  Trades,
  HistoricalTrades,
  AggTrades,
  Klines,
  ContinuousKlines,
  IndexPriceKlines,
  MarkPriceKlines,
  PremiumIndex,
  FundingRate,
  Ticker24hr,
  TickerPrice,
  BookTicker,
  AllForceOrders,
  AllOpenOrders,
  AllOrders,
  UserTrades,
  Order,
  PositionRisk,
  Balance,
  PositionSide,
  OpenInterest,
  OpenInterestHist,
  TopLongShortAccountRatio,
  TopLongShortPositionRatio,
  GlobalLongShortAccountRatio,
  TakerlongshortRatio,
  LvtKlines,
  IndexInfo,
  ChangeInitialLeverage,
  MarginType,
  PositionMargin,
  Account,
  OpenOrders,
  UserDataStream,
  Income,
}

pub enum AccountGeneral {
  ApiRestrictions,
}

impl AsRef<str> for API {
  fn as_ref(&self) -> &str {
    match self {
      API::SpotV3(route) => match route {
        SpotV3::Ping => "/api/v3/ping",
        SpotV3::Time => "/api/v3/time",
        SpotV3::ExchangeInfo => "/api/v3/exchangeInfo",
        SpotV3::Depth => "/api/v3/depth",
        SpotV3::Trades => "/api/v3/trades",
        SpotV3::HistoricalTrades => "/api/v3/historicalTrades",
        SpotV3::AggTrades => "/api/v3/aggTrades",
        SpotV3::Klines => "/api/v3/klines",
        SpotV3::AvgPrice => "/api/v3/avgPrice",
        SpotV3::Ticker24hr => "/api/v3/ticker/24hr",
        SpotV3::Price => "/api/v3/ticker/price",
        SpotV3::BookTicker => "/api/v3/ticker/bookTicker",
        SpotV3::Order => "/api/v3/order",
        SpotV3::OrderTest => "/api/v3/order/test",
        SpotV3::OpenOrders => "/api/v3/openOrders",
        SpotV3::AllOrders => "/api/v3/allOrders",
        SpotV3::Oco => "/api/v3/order/oco",
        SpotV3::OrderList => "/api/v3/orderList",
        SpotV3::AllOrderList => "/api/v3/allOrderList",
        SpotV3::OpenOrderList => "/api/v3/openOrderList",
        SpotV3::Account => "/api/v3/account_general",
        SpotV3::MyTrades => "/api/v3/myTrades",
        SpotV3::RateLimitOrder => "/api/v3/rateLimit/order",
        SpotV3::MyPreventedMatches => "/api/v3/myPreventedMatches",
        SpotV3::MyAllocations => "/api/v3/myAllocations",
        SpotV3::AccountCommissions => "/api/v3/account_general/commission",
        SpotV3::UserDataStream => "/api/v3/userDataStream",
      },
      API::Savings(route) => match route {
        Savings::AllCoins => "/savings/v1/capital/config/getall",
        Savings::AssetDetail => "/savings/v1/asset/assetDetail",
        Savings::DepositAddress => "/savings/v1/capital/deposit/address",
        Savings::SpotFuturesTransfer => "/savings/v1/futures/transfer",
      },
      API::Futures(route) => match route {
        Futures::Ping => "/futures/v1/ping",
        Futures::Time => "/futures/v1/time",
        Futures::ExchangeInfo => "/futures/v1/exchangeInfo",
        Futures::Depth => "/futures/v1/depth",
        Futures::Trades => "/futures/v1/trades",
        Futures::HistoricalTrades => "/futures/v1/historicalTrades",
        Futures::AggTrades => "/futures/v1/aggTrades",
        Futures::Klines => "/futures/v1/klines",
        Futures::ContinuousKlines => "/futures/v1/continuousKlines",
        Futures::IndexPriceKlines => "/futures/v1/indexPriceKlines",
        Futures::MarkPriceKlines => "/futures/v1/markPriceKlines",
        Futures::PremiumIndex => "/futures/v1/premiumIndex",
        Futures::FundingRate => "/futures/v1/fundingRate",
        Futures::Ticker24hr => "/futures/v1/ticker/24hr",
        Futures::TickerPrice => "/futures/v1/ticker/price",
        Futures::BookTicker => "/futures/v1/ticker/bookTicker",
        Futures::AllForceOrders => "/futures/v1/allForceOrders",
        Futures::AllOpenOrders => "/futures/v1/allOpenOrders",
        Futures::AllOrders => "/futures/v1/allOrders",
        Futures::UserTrades => "/futures/v1/userTrades",
        Futures::PositionSide => "/futures/v1/positionSide/dual",
        Futures::Order => "/futures/v1/order",
        Futures::PositionRisk => "/futures/v2/positionRisk",
        Futures::Balance => "/futures/v2/balance",
        Futures::OpenInterest => "/futures/v1/openInterest",
        Futures::OpenInterestHist => "/futures/data/openInterestHist",
        Futures::TopLongShortAccountRatio => "/futures/data/topLongShortAccountRatio",
        Futures::TopLongShortPositionRatio => "/futures/data/topLongShortPositionRatio",
        Futures::GlobalLongShortAccountRatio => "/futures/data/globalLongShortAccountRatio",
        Futures::TakerlongshortRatio => "/futures/data/takerlongshortRatio",
        Futures::LvtKlines => "/futures/v1/lvtKlines",
        Futures::IndexInfo => "/futures/v1/indexInfo",
        Futures::ChangeInitialLeverage => "/futures/v1/leverage",
        Futures::MarginType => "/futures/v1/marginType",
        Futures::PositionMargin => "/futures/v1/positionMargin",
        Futures::Account => "/futures/v2/account_general",
        Futures::OpenOrders => "/futures/v1/openOrders",
        Futures::UserDataStream => "/futures/v1/listenKey",
        Futures::Income => "/futures/v1/income",
      },
      API::AccountGeneral(route) => match route {
        AccountGeneral::ApiRestrictions => "/sapi/v1/account/apiRestrictions",
      },
    }
  }
}
