package org.knowm.xchange.liqui.service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.knowm.xchange.Exchange;
import org.knowm.xchange.currency.CurrencyPair;
import org.knowm.xchange.dto.Order;
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.NotAvailableFromExchangeException;
import org.knowm.xchange.liqui.LiquiAdapters;
import org.knowm.xchange.liqui.dto.LiquiException;
import org.knowm.xchange.liqui.dto.trade.LiquiCancelOrder;
import org.knowm.xchange.service.trade.TradeService;
import org.knowm.xchange.service.trade.params.CancelOrderByIdParams;
import org.knowm.xchange.service.trade.params.CancelOrderParams;
import org.knowm.xchange.service.trade.params.TradeHistoryParams;
import org.knowm.xchange.service.trade.params.orders.DefaultOpenOrdersParamCurrencyPair;
import org.knowm.xchange.service.trade.params.orders.OpenOrdersParamCurrencyPair;
import org.knowm.xchange.service.trade.params.orders.OpenOrdersParams;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LiquiTradeService extends LiquiTradeServiceRaw implements TradeService {

  private static final Logger LOG = LoggerFactory.getLogger(LiquiTradeService.class);

  public LiquiTradeService(final Exchange exchange) {
    super(exchange);
  }

  @Override
  public OpenOrders getOpenOrders() throws IOException {
    return LiquiAdapters.adaptActiveOrders(getActiveOrders());
  }

  @Override
  public OpenOrders getOpenOrders(final OpenOrdersParams params) throws IOException {
    if (params instanceof OpenOrdersParamCurrencyPair) {
      return LiquiAdapters.adaptActiveOrders(
          getActiveOrders(((OpenOrdersParamCurrencyPair) params).getCurrencyPair()));
    }

    throw new LiquiException("Unable to get open orders with the provided params: " + params);
  }

  @Override
  public String placeMarketOrder(final MarketOrder marketOrder) throws IOException {
    throw new NotAvailableFromExchangeException();
  }

  @Override
  public String placeLimitOrder(final LimitOrder limitOrder) throws IOException {
    return LiquiAdapters.adaptOrderId(placeLiquiLimitOrder(limitOrder));
  }

  @Override
  public boolean cancelOrder(final String orderId) throws IOException {
    try {
      final LiquiCancelOrder liquiCancelOrder = cancelOrder(Long.parseLong(orderId));
      return true;
    } catch (final LiquiException exception) {
      LOG.warn("Unable to cancel order({}).", orderId, exception);
      return false;
    }
  }

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

  @Override
  public UserTrades getTradeHistory(final TradeHistoryParams params) throws IOException {
    if (params instanceof LiquiTradeHistoryParams) {
      if (((LiquiTradeHistoryParams) params).getCurrencyPair() != null) {
        return LiquiAdapters.adaptTradesHistory(getTradeHistory());
      } else {
        return LiquiAdapters.adaptTradesHistory(
            getTradeHistory(
                ((LiquiTradeHistoryParams) params).getCurrencyPair(),
                ((LiquiTradeHistoryParams) params).getAmount()));
      }
    }

    throw new LiquiException("Unable to get trade history with the provided params: " + params);
  }

  @Override
  public LiquiTradeHistoryParams createTradeHistoryParams() {
    return new LiquiTradeHistoryParams();
  }

  @Override
  public DefaultOpenOrdersParamCurrencyPair createOpenOrdersParams() {
    return new DefaultOpenOrdersParamCurrencyPair();
  }

  @Override
  public Collection<Order> getOrder(final String... orderIds) throws IOException {
    final List<Order> orders = new ArrayList<>();

    for (final String orderId : orderIds) {
      orders.add(LiquiAdapters.adaptOrderInfo(getOrderInfo(Long.parseLong(orderId))));
    }
    return orders;
  }

  public static class LiquiTradeHistoryParams implements TradeHistoryParams {

    private CurrencyPair currencyPair = null;
    private int amount = 1000;

    public LiquiTradeHistoryParams() {}

    public CurrencyPair getCurrencyPair() {
      return currencyPair;
    }

    public void setCurrencyPair(final CurrencyPair currencyPair) {
      this.currencyPair = currencyPair;
    }

    public int getAmount() {
      return amount;
    }

    public void setAmount(final int amount) {
      this.amount = amount;
    }
  }
}

@@ -781,160 +781,9 @@
 ams.
-CancelOrderByIdParams;%0Aimport org.knowm.xchange.service.trade.params.CancelOrderParams;%0Aimport org.knowm.xchange.service.trade.params.TradeHistoryParams
+*
 ;%0Aim
@@ -3325,21 +3325,20 @@
 ams).get
-Amoun
+Limi
 t()));%0A 
@@ -4067,16 +4067,22 @@
 ryParams
+%0A     
  impleme
@@ -4103,16 +4103,71 @@
 ryParams
+, TradeHistoryParamCurrencyPair, TradeHistoryParamLimit
  %7B%0A%0A    
@@ -4208,16 +4208,17 @@
 = null;%0A
+%0A
     priv
@@ -4225,21 +4225,20 @@
 ate int 
-amoun
+limi
 t = 1000
@@ -4465,32 +4465,46 @@
 ncyPair;%0A    %7D%0A%0A
+    @Override%0A
     public int g
@@ -4502,20 +4502,23 @@
 lic 
-int getAmoun
+Integer getLimi
 t() 
@@ -4532,21 +4532,20 @@
  return 
-amoun
+limi
 t;%0A    %7D
@@ -4538,32 +4538,46 @@
 n limit;%0A    %7D%0A%0A
+    @Override%0A
     public void 
@@ -4583,30 +4583,26 @@
  set
-Amount(final int amoun
+Limit(Integer limi
 t) %7B
@@ -4617,22 +4617,20 @@
 his.
-amount = amoun
+limit = limi
 t;%0A 

Add TradeHistoryParamCurrencyPair, TradeHistoryParamLimit interfaces to LiquiTradeHistoryParams