package net.onrc.onos.core.flowprogrammer;

import java.util.Collection;

import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.internal.OFMessageFuture;
import net.floodlightcontroller.core.module.IFloodlightService;
import net.onrc.onos.core.util.FlowEntry;
import net.onrc.onos.core.util.Pair;

import org.openflow.protocol.OFBarrierReply;
import org.openflow.protocol.OFMessage;

/**
 * FlowPusherService is a service to send message to switches in proper rate.
 * Conceptually a queue is attached to each switch, and FlowPusherService
 * read a message from queue and send it to switch in order.
 * To guarantee message has been installed, FlowPusherService can add barrier
 * message to queue and can notify when barrier message is sent to switch.
 */
public interface IFlowPusherService extends IFloodlightService {
    public static enum MsgPriority {
        HIGH,        // High priority: e.g. flow synchronization
        NORMAL,        // Normal priority
//              LOW,            // Low priority, not needed for now
    }

    public static enum QueueState {
        READY,        // Queues with all priority are at work
        SUSPENDED,    // Only prior queue is at work
        UNKNOWN
    }

    /**
     * Create a queue correspondent to the switch.
     *
     * @param sw Switch to which new queue is attached.
     * @return true if new queue is successfully created.
     */
    boolean createQueue(IOFSwitch sw);

    /**
     * Delete a queue correspondent to the switch.
     * Messages remains in queue will be all sent before queue is deleted.
     *
     * @param sw Switch of which queue is deleted.
     * @return true if queue is successfully deleted.
     */
    boolean deleteQueue(IOFSwitch sw);

    /**
     * Delete a queue correspondent to the switch.
     * By setting force flag on, queue will be deleted immediately.
     *
     * @param sw        Switch of which queue is deleted.
     * @param forceStop If this flag is set to true, queue will be deleted
     *                  immediately regardless of any messages in the queue.
     *                  If false, all messages will be sent to switch and queue will
     *                  be deleted after that.
     * @return true if queue is successfully deleted or flagged to be deleted.
     */
    boolean deleteQueue(IOFSwitch sw, boolean forceStop);

    /**
     * Add a message to the queue of the switch with normal priority.
     * <p/>
     * Note: Notification is NOT delivered for the pushed message.
     *
     * @param sw  Switch to which message is pushed.
     * @param msg Message object to be added.
     * @return true if message is successfully added to a queue.
     */
    boolean add(IOFSwitch sw, OFMessage msg);

    /**
     * Add a message to the queue of the switch with specific priority.
     *
     * @param sw       Switch to which message is pushed.
     * @param msg      Message object to be added.
     * @param priority Sending priority of the message.
     * @return true if message is successfully added to a queue.
     */
    boolean add(IOFSwitch sw, OFMessage msg, MsgPriority priority);

    /**
     * Push a collection of Flow Entries to the corresponding switches
     * with normal priority.
     * <p/>
     * Note: Notification is delivered for the Flow Entries that
     * are pushed successfully.
     *
     * @param entries the collection of <IOFSwitch, FlowEntry> pairs
     *                to push.
     */
    void pushFlowEntries(Collection<Pair<IOFSwitch, FlowEntry>> entries);

    /**
     * Push a collection of Flow Entries to the corresponding switches
     * with specific priority.
     * <p/>
     * Note: Notification is delivered for the Flow Entries that
     * are pushed successfully.
     *
     * @param entries  the collection of <IOFSwitch, FlowEntry> pairs
     *                 to push.
     * @param priority Sending priority of flow entries.
     */
    void pushFlowEntries(Collection<Pair<IOFSwitch, FlowEntry>> entries,
                         MsgPriority priority);

    /**
     * Create a message from FlowEntry and add it to the queue of the
     * switch with normal priority.
     * <p/>
     * Note: Notification is delivered for the Flow Entries that
     * are pushed successfully.
     *
     * @param sw        Switch to which message is pushed.
     * @param flowEntry FlowEntry object used for creating message.
     */
    void pushFlowEntry(IOFSwitch sw, FlowEntry flowEntry);

    /**
     * Create a message from FlowEntry and add it to the queue of the
     * switch with specific priority.
     * <p/>
     * Note: Notification is delivered for the Flow Entries that
     * are pushed successfully.
     *
     * @param sw        Switch to which message is pushed.
     * @param flowEntry FlowEntry object used for creating message.
     */
    void pushFlowEntry(IOFSwitch sw, FlowEntry flowEntry,
                       MsgPriority priority);

    /**
     * Set sending rate to a switch.
     *
     * @param sw   Switch.
     * @param rate Rate in bytes/ms.
     */
    public void setRate(IOFSwitch sw, long rate);

    /**
     * Add BARRIER message to queue and wait for reply.
     *
     * @param sw Switch to which barrier message is pushed.
     * @return BARRIER_REPLY message sent from switch.
     */
    OFBarrierReply barrier(IOFSwitch sw);

    /**
     * Add BARRIER message to queue asynchronously.
     *
     * @param sw Switch to which barrier message is pushed.
     * @return Future object of BARRIER_REPLY message which will be sent from switch.
     */
    OFMessageFuture<OFBarrierReply> barrierAsync(IOFSwitch sw);

    /**
     * Suspend pushing message to a switch.
     *
     * @param sw Switch to be suspended pushing message.
     * @return true if success
     */
    boolean suspend(IOFSwitch sw);

    /**
     * Resume pushing message to a switch.
     *
     * @param sw Switch to be resumed pushing message.
     * @return true if success
     */
    boolean resume(IOFSwitch sw);

    /**
     * Get state of queue attached to a switch.
     *
     * @param sw Switch to be checked.
     * @return State of queue.
     */
    QueueState getState(IOFSwitch sw);
}
