package com.icesecret.ex;


import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by charlie on 17/10/31.
 */
public class MemOrderBook extends PrintableOrderBook implements OrderBook {
    private List<LimitOrder> list = Collections.synchronizedList(new LinkedList<>());
    private Map<String, LimitOrder> map = new ConcurrentHashMap<>();
    private Comparator<LimitOrder> comparable=Comparator.comparing(LimitOrder::getPrice);

    public static volatile int LIMIT = 5;


    PersistOrderBook persistOrderBook = new PersistOrderBook();


    @Override
    public synchronized void put(LimitOrder limitOrder) {
        add(limitOrder);
        Collections.sort(list, comparable);
        if (list.size() > LIMIT) {
            int index = list.size() - 1;
            LimitOrder over = list.remove(index);
            map.remove(over.getId());
            persistOrderBook.put(over);
        }
    }

    @Override
    public void cancel(String orderId) {
        LimitOrder limitOrder = new LimitOrder();
        limitOrder.setId(orderId);
        limitOrder.setStatus(OrderStatus.Cancelled);
        remove(limitOrder);
        Collections.sort(list, comparable);

    }

    private void add(LimitOrder limitOrder) {
        list.add(limitOrder);
        map.put(limitOrder.getId(), limitOrder);
    }

    private void remove(LimitOrder limitOrder) {
        list.remove(limitOrder);
        map.remove(limitOrder.getId());
        persistOrderBook.put(limitOrder);
    }

    @Override
    public void update(String orderId, Double change) {
        LimitOrder limitOrder = map.get(orderId);
        if (limitOrder != null) {
            limitOrder.setAmount(limitOrder.getAmount() + change);
            if (limitOrder.getAmount() <= 0) {
                limitOrder.setStatus(OrderStatus.Completed);
                //complete order
                remove(limitOrder);
            }
        }
    }

    @Override
    public List<LimitOrder> getOrderList() {
        Object[] src = list.toArray();
        LimitOrder[] dest = new LimitOrder[src.length];
        System.arraycopy(src, 0, dest, 0, src.length);
        return Arrays.asList(dest);
    }

    @Override
    public OrderBook getPersistOrderBook() {
        return persistOrderBook;
    }

    @Override
    public TradePair getTradePair() {
        return null;
    }

    @Override
    public TradeSide getTradeSide() {
        return null;
    }
}
