/**
 *
 */
package net.floodlightcontroller.util;

import java.util.ArrayList;

/**
 * @author subrata
 */

public class EventHistory<T> {
    public static final int EV_HISTORY_DEFAULT_SIZE = 1024;

    public String description;
    public int event_history_size;
    public int current_index;
    public boolean full; // true if all are in use
    public ArrayList<Event> events;

    public String getDescription() {
        return description;
    }

    public int getEvent_history_size() {
        return event_history_size;
    }

    public int getCurrent_index() {
        return current_index;
    }

    public boolean isFull() {
        return full;
    }

    public ArrayList<Event> getEvents() {
        return events;
    }

    public class Event {
        public EventHistoryBaseInfo base_info;
        public T info;
    }

    public enum EvState {
        FREE,             // no valid event written yet
        BEING_MODIFIED,   // event is being updated with new value, skip
        ACTIVE,           // event is active and can be displayed
    }

    public enum EvAction {
        ADDED,   // specific entry added
        REMOVED, // specific entry removed
        UPDATED, // Entry updated
        BLOCKED, // Blocked - used for Attachment Points
        UNBLOCKED,
        CLEARED,  // All entries are removed
        PKT_IN,
        PKT_OUT,
        SWITCH_CONNECTED,
        SWITCH_DISCONNECTED,
        LINK_ADDED,
        LINK_DELETED,
        LINK_PORT_STATE_UPDATED,
        CLUSTER_ID_CHANGED_FOR_CLUSTER,
        CLUSTER_ID_CHANGED_FOR_A_SWITCH,
    }

    // Constructor
    public EventHistory(int maxEvents, String desc) {
        events = new ArrayList<Event>(maxEvents);

        for (int idx = 0; idx < maxEvents; idx++) {
            Event evH = new Event();
            evH.base_info = new EventHistoryBaseInfo();
            evH.info = null;
            evH.base_info.state = EvState.FREE;
            evH.base_info.idx = idx;
            events.add(idx, evH);
        }

        description = "Event-History:" + desc;
        event_history_size = maxEvents;
        current_index = 0;
        full = false;
    }

    // Constructor for default size
    public EventHistory(String desc) {
        this(EV_HISTORY_DEFAULT_SIZE, desc);
    }

    // Copy constructor - copy latest k items of the event history
    public EventHistory(EventHistory<T> eventHist, int latestK) {

        if (eventHist == null) {
            description = "No event found";
            return;
        }
        int curSize = (eventHist.full) ? eventHist.event_history_size :
                eventHist.current_index;
        int size = (latestK < curSize) ? latestK : curSize;
        int evIdx = eventHist.current_index;
        int topSz = (evIdx >= size) ? size : evIdx;

        // Need to create a new one since size is different
        events = new ArrayList<Event>(size);

        // Get the top part
        int origIdx = evIdx;
        for (int idx = 0; idx < topSz; idx++) {
            Event evH = eventHist.events.get(--origIdx);
            evH.base_info.idx = idx;
            events.add(idx, evH);
        }

        // Get the bottom part
        origIdx = eventHist.event_history_size;
        for (int idx = topSz; idx < size; idx++) {
            Event evH = eventHist.events.get(--origIdx);
            evH.base_info.idx = idx;
            events.add(idx, evH);
        }

        description = eventHist.description;
        event_history_size = size;
        current_index = 0; // since it is full
        full = true;
    }

    // Get an index for writing a new event. This method is synchronized for
    // this event history infra. to be thread-safe. Once the index is obtained
    // by the caller event at the index is updated without any lock
    public synchronized int NextIdx() {
        // curIdx should be in the 0 to evArraySz-1
        if (current_index == (event_history_size - 1)) {
            current_index = 0;
            full = true;
            return (event_history_size - 1);
        } else {
            current_index++;
            return (current_index - 1);
        }
    }

    /**
     * Add an event to the event history
     * Eliminate java garbage cration by reusing the same object T
     * Supplied object t is used to populate the event history array
     * and the current object at that array location is returned to the
     * calling process so that the calling process can use that object
     * for the next event of the same type
     *
     * @param t
     * @param op
     * @return
     */

    public T put(T t, EvAction action) {
        int idx = NextIdx();
        Event evH = events.get(idx);
        evH.base_info.state = EvState.BEING_MODIFIED;
        evH.base_info.time_ms = System.currentTimeMillis();
        evH.base_info.action = action;
        T temp = evH.info;
        evH.info = t;
        evH.base_info.state = EvState.ACTIVE;
        return temp;
    }

    /**
     * Clear the event history, needs to be done under lock
     */
    public void clear() {
        for (int idx = 0; idx < event_history_size; idx++) {
            Event evH = events.get(idx);
            evH.base_info.state = EvState.FREE;
            current_index = 0;
            full = false;
        }
    }
}
