/**
 * 
 */
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;
        }
    }
}
