package org.knowm.xchange.gateio.service;

import java.io.IOException;
import java.util.Collection;
import java.util.List;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.trade.LimitOrder;
import org.knowm.xchange.dto.trade.MarketOrder;
import org.knowm.xchange.dto.trade.OpenOrders;
import org.knowm.xchange.dto.trade.UserTrades;
import org.knowm.xchange.exceptions.ExchangeException;
import org.knowm.xchange.exceptions.NotAvailableFromExchangeException;
import org.knowm.xchange.gateio.GateioAdapters;
import org.knowm.xchange.gateio.dto.trade.GateioOpenOrders;
import org.knowm.xchange.gateio.dto.trade.GateioTrade;
import org.knowm.xchange.service.trade.TradeService;
import org.knowm.xchange.service.trade.params.CancelOrderParams;
import org.knowm.xchange.service.trade.params.DefaultTradeHistoryParamCurrencyPair;
import org.knowm.xchange.service.trade.params.TradeHistoryParamCurrencyPair;
import org.knowm.xchange.service.trade.params.TradeHistoryParams;
import org.knowm.xchange.service.trade.params.orders.OpenOrdersParams;

public class GateioTradeService extends GateioTradeServiceRaw implements TradeService {

  /**
   * Constructor
   *
   * @param exchange
   */
  public GateioTradeService(Exchange exchange) {

    super(exchange);
  }

  @Override
  public OpenOrders getOpenOrders() throws IOException {
    return getOpenOrders(createOpenOrdersParams());
  }

  @Override
  public OpenOrders getOpenOrders(OpenOrdersParams params) throws IOException {
    GateioOpenOrders openOrders = super.getGateioOpenOrders();
    Collection<CurrencyPair> currencyPairs = exchange.getExchangeSymbols();

    return GateioAdapters.adaptOpenOrders(openOrders, currencyPairs);
  }

  @Override
  public String placeMarketOrder(MarketOrder marketOrder) throws IOException {

    throw new NotAvailableFromExchangeException();
  }

  /**
   * Submits a Limit Order to be executed on the Gateio Exchange for the desired market defined by
   * {@code CurrencyPair}. WARNING - Gateio will return true regardless of whether or not an order
   * actually gets created. The reason for this is that orders are simply submitted to a queue in
   * their back-end. One example for why an order might not get created is because there are
   * insufficient funds. The best attempt you can make to confirm that the order was created is to
   * poll {@link #getOpenOrders}. However, if the order is created and executed before it is caught
   * in its open state from calling {@link #getOpenOrders} then the only way to confirm would be
   * confirm the expected difference in funds available for your account.
   *
   * @return String "true"/"false" Used to determine if the order request was submitted
   *     successfully.
   */
  @Override
  public String placeLimitOrder(LimitOrder limitOrder) throws IOException {

    return String.valueOf(super.placeGateioLimitOrder(limitOrder));
  }

  @Override
  public boolean cancelOrder(String orderId) throws IOException {
    throw new NotAvailableFromExchangeException();
  }

  @Override
  public boolean cancelOrder(CancelOrderParams orderParams) throws IOException {
    if (orderParams instanceof GateioCancelOrderParams) {
      return cancelOrder(
          ((GateioCancelOrderParams) orderParams).getOrderId(),
          ((GateioCancelOrderParams) orderParams).getCurrencyPair());
    } else {
      return false;
    }
  }

  /** Required parameter: {@link TradeHistoryParamCurrencyPair} */
  @Override
  public UserTrades getTradeHistory(TradeHistoryParams params)
      throws ExchangeException, IOException {

    CurrencyPair pair = ((TradeHistoryParamCurrencyPair) params).getCurrencyPair();
    List<GateioTrade> userTrades = getGateioTradeHistory(pair).getTrades();

    return GateioAdapters.adaptUserTrades(userTrades);
  }

  @Override
  public TradeHistoryParamCurrencyPair createTradeHistoryParams() {

    return new DefaultTradeHistoryParamCurrencyPair();
  }

  @Override
  public OpenOrdersParams createOpenOrdersParams() {
    return null;
  }
}

@@ -780,252 +780,9 @@
 ams.
-CancelOrderParams;%0Aimport org.knowm.xchange.service.trade.params.DefaultTradeHistoryParamCurrencyPair;%0Aimport org.knowm.xchange.service.trade.params.TradeHistoryParamCurrencyPair;%0Aimport org.knowm.xchange.service.trade.params.TradeHistoryParams
+*
 ;%0Aim
@@ -2959,39 +2959,97 @@
 tanceof 
-GateioCancelOrderParams
+CancelOrderByIdParams &&%0A        orderParams instanceof CancelOrderByCurrencyPair
 ) %7B%0A    
@@ -3074,38 +3074,32 @@
 er(%0A          ((
-Gateio
 CancelOrderParam
@@ -3085,32 +3085,36 @@
    ((CancelOrder
+ById
 Params) orderPar
@@ -3144,22 +3144,16 @@
       ((
-Gateio
 CancelOr
@@ -3155,22 +3155,30 @@
 celOrder
-Params
+ByCurrencyPair
 ) orderP

Make generic cancelOrder method independent of GateIO specific class structure by using core classes CancelOrderByIdParams, CancelOrderByCurrencyPair instead of GateioCancelOrderParams. API consumers which use GateioCancelOrderParams do not effected from this update (backward compatability is ensured.)