package net.onrc.onos.ofcontroller.flowprogrammer;

import java.util.Collection;

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

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

/**
 * 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.
 *
 * @author Naoki Shiota
 */
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.
     * @return true if message is successfully added to a queue.
     */
    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.
     * @return true if message is successfully added to a queue.
     */
    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);
}
