package org.knowm.xchange.okcoin;

import org.knowm.xchange.BaseExchange;
import org.knowm.xchange.ExchangeSpecification;
import org.knowm.xchange.okcoin.service.OkCoinAccountService;
import org.knowm.xchange.okcoin.service.OkCoinFuturesAccountService;
import org.knowm.xchange.okcoin.service.OkCoinFuturesMarketDataService;
import org.knowm.xchange.okcoin.service.OkCoinFuturesTradeService;
import org.knowm.xchange.okcoin.service.OkCoinMarketDataService;
import org.knowm.xchange.okcoin.service.OkCoinTradeService;
import si.mazi.rescu.SynchronizedValueFactory;

public class OkCoinExchange extends BaseExchange {

  /** Adjust host parameters depending on exchange specific parameters */
  private static void concludeHostParams(ExchangeSpecification exchangeSpecification) {

    if (exchangeSpecification.getExchangeSpecificParameters() != null) {
      if (exchangeSpecification.getExchangeSpecificParametersItem("Use_Intl").equals(true)
          && exchangeSpecification.getExchangeSpecificParametersItem("Use_Futures").equals(false)) {

        exchangeSpecification.setSslUri("https://www.OKCoin.com/api");
        exchangeSpecification.setHost("www.OKCoin.com");

      } else if (exchangeSpecification.getExchangeSpecificParametersItem("Use_Intl").equals(true)
          && exchangeSpecification.getExchangeSpecificParametersItem("Use_Futures").equals(true)) {

        exchangeSpecification.setSslUri("https://www.OKCoin.com/api");
        exchangeSpecification.setHost("www.OKCoin.com");
      }
    }
  }

  /** Extract futures leverage used by spec */
  private static int futuresLeverageOfConfig(ExchangeSpecification exchangeSpecification) {

    if (exchangeSpecification.getExchangeSpecificParameters().containsKey("Futures_Leverage")) {
      return Integer.valueOf(
          (String) exchangeSpecification.getExchangeSpecificParameters().get("Futures_Leverage"));
    } else {
      // default choice of 10x leverage is "safe" choice and default by OkCoin.
      return 10;
    }
  }

  /** Extract contract used by spec */
  public static FuturesContract futuresContractOfConfig(
      ExchangeSpecification exchangeSpecification) {

    FuturesContract contract;

    if (exchangeSpecification.getExchangeSpecificParameters().containsKey("Futures_Contract")) {
      contract =
          (FuturesContract)
              exchangeSpecification.getExchangeSpecificParameters().get("Futures_Contract");
    } else if (exchangeSpecification
        .getExchangeSpecificParameters()
        .containsKey("Futures_Contract_String")) {
      contract =
          FuturesContract.valueOfIgnoreCase(
              FuturesContract.class,
              (String)
                  exchangeSpecification
                      .getExchangeSpecificParameters()
                      .get("Futures_Contract_String"));
    } else {
      throw new RuntimeException(
          "`Futures_Contract` or `Futures_Contract_String` not defined in exchange specific parameters.");
    }

    return contract;
  }

  @Override
  public void applySpecification(ExchangeSpecification exchangeSpecification) {

    super.applySpecification(exchangeSpecification);

    if (exchangeSpecification.getExchangeSpecificParametersItem("Use_Intl").equals(false)
        && exchangeSpecification.getExchangeSpecificParametersItem("Use_Futures").equals(true)) {
      throw new RuntimeException(
          "Futures only available on international version. Set `Use_Intl` to true.");
    }

    concludeHostParams(exchangeSpecification);
  }

  @Override
  protected void initServices() {

    concludeHostParams(exchangeSpecification);

    if (exchangeSpecification.getExchangeSpecificParameters() != null
        && exchangeSpecification.getExchangeSpecificParametersItem("Use_Futures").equals(true)) {
      FuturesContract contract = futuresContractOfConfig(exchangeSpecification);

      this.marketDataService = new OkCoinFuturesMarketDataService(this, contract);
      if (exchangeSpecification.getApiKey() != null) {
        this.accountService = new OkCoinFuturesAccountService(this);
        this.tradeService =
            new OkCoinFuturesTradeService(
                this, contract, futuresLeverageOfConfig(exchangeSpecification));
      }
    } else {
      this.marketDataService = new OkCoinMarketDataService(this);
      if (exchangeSpecification.getApiKey() != null) {
        this.accountService = new OkCoinAccountService(this);
        this.tradeService = new OkCoinTradeService(this);
      }
    }
  }

  @Override
  public ExchangeSpecification getDefaultExchangeSpecification() {

    ExchangeSpecification exchangeSpecification =
        new ExchangeSpecification(this.getClass().getCanonicalName());
    exchangeSpecification.setSslUri("https://www.OKCoin.com/api");
    exchangeSpecification.setHost("www.OKCoin.com");
    exchangeSpecification.setExchangeName("OKCoin");
    exchangeSpecification.setExchangeDescription(
        "OKCoin is a globally oriented crypto-currency trading platform.");

    // set to true to automatically use the Intl_ parameters for ssluri and host
    exchangeSpecification.setExchangeSpecificParametersItem("Use_Intl", false);
    exchangeSpecification.setExchangeSpecificParametersItem("Use_Futures", false);

    return exchangeSpecification;
  }

  @Override
  public SynchronizedValueFactory<Long> getNonceFactory() {

    // This exchange doesn't use a nonce for authentication
    return null;
  }

  @Override
  public String getMetaDataFileName(ExchangeSpecification exchangeSpecification) {

    if (exchangeSpecification.getExchangeSpecificParametersItem("Use_Intl").equals(false)) {
      return exchangeSpecification
              .getExchangeName()
              .toLowerCase()
              .replace(" ", "")
              .replace("-", "")
              .replace(".", "")
          + "_china";
    } else {
      if (exchangeSpecification.getExchangeSpecificParametersItem("Use_Futures").equals(true)) {
        return exchangeSpecification
                .getExchangeName()
                .toLowerCase()
                .replace(" ", "")
                .replace("-", "")
                .replace(".", "")
            + "_futures";
      } else {
        return exchangeSpecification
                .getExchangeName()
                .toLowerCase()
                .replace(" ", "")
                .replace("-", "")
                .replace(".", "")
            + "_intl";
      }
    }
  }
}

@@ -1084,38 +1084,36 @@
 ri(%22https://www.
-OKCoin
+okex
 .com/api%22);%0A    
@@ -1143,38 +1143,36 @@
 on.setHost(%22www.
-OKCoin
+okex
 .com%22);%0A%0A      %7D
@@ -1408,38 +1408,36 @@
 ri(%22https://www.
-OKCoin
+okex
 .com/api%22);%0A    
@@ -1467,38 +1467,36 @@
 on.setHost(%22www.
-OKCoin
+okex
 .com%22);%0A      %7D%0A
@@ -4744,30 +4744,28 @@
 https://www.
-OKCoin
+okex
 .com/api%22);%0A
@@ -4803,22 +4803,20 @@
 st(%22www.
-OKCoin
+okex
 .com%22);%0A

revert changes