/**
 *    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
 *
 *    Licensed under the Apache License, Version 2.0 (the "License"); you may
 *    not use this file except in compliance with the License. You may obtain
 *    a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 *    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 *    License for the specific language governing permissions and limitations
 *    under the License.
 **/

package net.floodlightcontroller.core.internal;

import java.io.FileInputStream;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.Set;
import java.util.Stack;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IListener.Command;
import net.floodlightcontroller.core.IOFMessageListener;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.IOFSwitch.PortChangeType;
import net.floodlightcontroller.core.IOFSwitchFilter;
import net.floodlightcontroller.core.IOFSwitchListener;
import net.floodlightcontroller.core.IUpdate;
import net.floodlightcontroller.core.annotations.LogMessageDoc;
import net.floodlightcontroller.core.annotations.LogMessageDocs;
import net.floodlightcontroller.core.internal.OFChannelHandler.RoleRecvStatus;
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.util.ListenerDispatcher;
import net.floodlightcontroller.core.web.CoreWebRoutable;
import net.floodlightcontroller.debugcounter.IDebugCounter;
import net.floodlightcontroller.debugcounter.IDebugCounterService;
import net.floodlightcontroller.debugcounter.IDebugCounterService.CounterException;
import net.floodlightcontroller.debugcounter.IDebugCounterService.CounterType;
import net.floodlightcontroller.debugevent.IDebugEventService;
import net.floodlightcontroller.debugevent.IDebugEventService.EventColumn;
import net.floodlightcontroller.debugevent.IDebugEventService.EventFieldType;
import net.floodlightcontroller.debugevent.IDebugEventService.EventType;
import net.floodlightcontroller.debugevent.IDebugEventService.MaxEventsRegistered;
import net.floodlightcontroller.debugevent.IEventUpdater;
import net.floodlightcontroller.debugevent.NullDebugEvent;
import net.floodlightcontroller.restserver.IRestApiService;
import net.floodlightcontroller.threadpool.IThreadPoolService;
import net.floodlightcontroller.util.LoadMonitor;
import net.onrc.onos.core.drivermanager.DriverManager;
import net.onrc.onos.core.linkdiscovery.ILinkDiscoveryService;
import net.onrc.onos.core.packet.Ethernet;
import net.onrc.onos.core.registry.IControllerRegistryService;
import net.onrc.onos.core.registry.IControllerRegistryService.ControlChangeCallback;
import net.onrc.onos.core.registry.RegistryException;
import net.onrc.onos.core.util.Dpid;
import net.onrc.onos.core.util.OnosInstanceId;

import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFFactories;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFType;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.protocol.match.MatchField;
import org.projectfloodlight.openflow.protocol.match.MatchFields;
import org.projectfloodlight.openflow.types.EthType;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.util.HexString;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The main controller class. Handles all setup and network listeners -
 * Distributed ownership control of switch through IControllerRegistryService
 */
public class Controller implements IFloodlightProviderService {

    protected final static Logger log = LoggerFactory.getLogger(Controller.class);
    static final String ERROR_DATABASE =
            "The controller could not communicate with the system database.";
    protected static OFFactory factory13 = OFFactories.getFactory(OFVersion.OF_13);
    protected static OFFactory factory10 = OFFactories.getFactory(OFVersion.OF_10);

    // connectedSwitches cache contains all connected switch's channelHandlers
    // including ones where this controller is a master/equal/slave controller
    // as well as ones that have not been activated yet
    protected ConcurrentHashMap<Long, OFChannelHandler> connectedSwitches;
    // These caches contains only those switches that are active
    protected ConcurrentHashMap<Long, IOFSwitch> activeMasterSwitches;
    protected ConcurrentHashMap<Long, IOFSwitch> activeEqualSwitches;
    // lock to synchronize on, when manipulating multiple caches above
    private Object multiCacheLock;

    // The controllerNodeIPsCache maps Controller IDs to their IP address.
    // It's only used by handleControllerNodeIPsChanged
    protected HashMap<String, String> controllerNodeIPsCache;
    protected BlockingQueue<IUpdate> updates;

    protected ConcurrentMap<OFType, ListenerDispatcher<OFType, IOFMessageListener>> messageListeners;
    protected Set<IOFSwitchListener> switchListeners;

    // Module dependencies
    protected IRestApiService restApi;
    protected IThreadPoolService threadPool;
    protected IControllerRegistryService registryService;
    protected IDebugCounterService debugCounters;
    protected IDebugEventService debugEvents;

    protected ILinkDiscoveryService linkDiscovery;

    // Configuration options
    protected int openFlowPort = 6633;
    protected int workerThreads = 0;

    // The id for this controller node. Should be unique for each controller
    // node in a controller cluster.
    private OnosInstanceId onosInstanceId = new OnosInstanceId("localhost");

    // defined counters
    private Counters counters;
    // Event IDs for debug events
    protected IEventUpdater<SwitchEvent> evSwitch;

    // Load monitor for overload protection
    protected final boolean overload_drop =
            Boolean.parseBoolean(System.getProperty("overload_drop", "false"));
    protected final LoadMonitor loadmonitor = new LoadMonitor(log);

    // Start time of the controller
    protected long systemStartTime;

    // Flag to always flush flow table on switch reconnect (HA or otherwise)
    protected boolean alwaysClearFlowsOnSwAdd = false;

    // Perf. related configuration
    protected static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;
    protected static final int BATCH_MAX_SIZE = 100;
    protected static final boolean ALWAYS_DECODE_ETH = true;

    // ******************************
    // Switch Management and Updates
    // ******************************

    /**
     * Switch updates are sent to all IOFSwitchListeners. A switch that is
     * connected to this controller instance, but not activated, is not
     * available for updates.
     *
     * In ONOS, each controller instance can simultaneously serve in a MASTER
     * role for some connected switches, and in a EQUAL role for other connected
     * switches. The EQUAL role can be treated as a SLAVE role, by ensuring that
     * the controller instance never sends packets or commands out to the
     * switch. Activated switches, either with Controller Role MASTER or EQUAL
     * are announced as updates. We also support announcements of controller
     * role transitions from MASTER --> EQUAL, and EQUAL --> MASTER, for an
     * individual switch.
     *
     * Disconnection of only activated switches are announced. Finally, changes
     * to switch ports are announced with a portChangeType (see @IOFSwitch)
     *
     * @author saurav
     */
    public enum SwitchUpdateType {
        /** switch activated with this controller's role as MASTER */
        ACTIVATED_MASTER,
        /**
         * switch activated with this controller's role as EQUAL. listener can
         * treat this controller's role as SLAVE by not sending packets or
         * commands to the switch
         */
        ACTIVATED_EQUAL,
        /** this controller's role for this switch changed from Master to Equal */
        MASTER_TO_EQUAL,
        /** this controller's role for this switch changed form Equal to Master */
        EQUAL_TO_MASTER,
        /** A previously activated switch disconnected */
        DISCONNECTED,
        /** Port changed on a previously activated switch */
        PORTCHANGED,
    }

    /**
     * Update message indicating a switch was added or removed ONOS: This
     * message extended to indicate Port add or removed event.
     */
    protected class SwitchUpdate implements IUpdate {
        public long getSwId() {
            return swId;
        }

        public SwitchUpdateType getSwitchUpdateType() {
            return switchUpdateType;
        }

        public PortChangeType getPortChangeType() {
            return changeType;
        }

        private final long swId;
        private final SwitchUpdateType switchUpdateType;
        private final OFPortDesc port;
        private final PortChangeType changeType;

        public SwitchUpdate(long swId, SwitchUpdateType switchUpdateType) {
            this(swId, switchUpdateType, null, null);
        }

        public SwitchUpdate(long swId,
                SwitchUpdateType switchUpdateType,
                OFPortDesc port,
                PortChangeType changeType) {
            if (switchUpdateType == SwitchUpdateType.PORTCHANGED) {
                if (port == null) {
                    throw new NullPointerException("Port must not be null " +
                            "for PORTCHANGED updates");
                }
                if (changeType == null) {
                    throw new NullPointerException("ChangeType must not be " +
                            "null for PORTCHANGED updates");
                }
            } else {
                if (port != null || changeType != null) {
                    throw new IllegalArgumentException("port and changeType " +
                            "must be null for " + switchUpdateType +
                            " updates");
                }
            }
            this.swId = swId;
            this.switchUpdateType = switchUpdateType;
            this.port = port;
            this.changeType = changeType;
        }

        @Override
        public void dispatch() {
            if (log.isTraceEnabled()) {
                log.trace("Dispatching switch update {} {}",
                        HexString.toHexString(swId), switchUpdateType);
            }
            if (switchListeners != null) {
                for (IOFSwitchListener listener : switchListeners) {
                    switch (switchUpdateType) {
                    case ACTIVATED_MASTER:
                        // don't count here. We have more specific
                        // counters before the update is created
                        listener.switchActivatedMaster(swId);
                        break;
                    case ACTIVATED_EQUAL:
                        // don't count here. We have more specific
                        // counters before the update is created
                        listener.switchActivatedEqual(swId);
                        break;
                    case MASTER_TO_EQUAL:
                        listener.switchMasterToEqual(swId);
                        break;
                    case EQUAL_TO_MASTER:
                        listener.switchEqualToMaster(swId);
                        break;
                    case DISCONNECTED:
                        // don't count here. We have more specific
                        // counters before the update is created
                        listener.switchDisconnected(swId);
                        break;
                    case PORTCHANGED:
                        counters.switchPortChanged.updateCounterWithFlush();
                        listener.switchPortChanged(swId, port, changeType);
                        break;
                    }
                }
            }
        }

    }

    protected boolean addConnectedSwitch(long dpid, OFChannelHandler h) {
        if (connectedSwitches.get(dpid) != null) {
            log.error("Trying to add connectedSwitch but found a previous "
                    + "value for dpid: {}", dpid);
            return false;
        } else {
            connectedSwitches.put(dpid, h);
            return true;
        }
    }

    /**
     * Switch Events
     */
    @Override
    public void addSwitchEvent(long dpid, String reason, boolean flushNow) {
        if (flushNow)
            evSwitch.updateEventWithFlush(new SwitchEvent(dpid, reason));
        else
            evSwitch.updateEventNoFlush(new SwitchEvent(dpid, reason));
    }

    private boolean validActivation(long dpid) {
        if (connectedSwitches.get(dpid) == null) {
            log.error("Trying to activate switch but is not in "
                    + "connected switches: dpid {}. Aborting ..",
                    HexString.toHexString(dpid));
            return false;
        }
        if (activeMasterSwitches.get(dpid) != null ||
                activeEqualSwitches.get(dpid) != null) {
            log.error("Trying to activate switch but it is already "
                    + "activated: dpid {}. Found in activeMaster: {} "
                    + "Found in activeEqual: {}. Aborting ..", new Object[] {
                    HexString.toHexString(dpid),
                    (activeMasterSwitches.get(dpid) == null) ? 'Y' : 'N',
                    (activeEqualSwitches.get(dpid) == null) ? 'Y' : 'N'});
            counters.switchWithSameDpidActivated.updateCounterWithFlush();
            return false;
        }
        return true;
    }

    /**
     * Called when a switch is activated, with this controller's role as MASTER
     */
    protected boolean addActivatedMasterSwitch(long dpid, IOFSwitch sw) {
        synchronized (multiCacheLock) {
            if (!validActivation(dpid))
                return false;
            activeMasterSwitches.put(dpid, sw);
        }

        // update counters and events
        counters.switchActivated.updateCounterWithFlush();
        evSwitch.updateEventWithFlush(new SwitchEvent(dpid, "activeMaster"));
        addUpdateToQueue(new SwitchUpdate(dpid,
                SwitchUpdateType.ACTIVATED_MASTER));
        return true;
    }

    /**
     * Called when a switch is activated, with this controller's role as EQUAL
     */
    protected boolean addActivatedEqualSwitch(long dpid, IOFSwitch sw) {
        synchronized (multiCacheLock) {
            if (!validActivation(dpid))
                return false;
            activeEqualSwitches.put(dpid, sw);
        }
        // update counters and events
        counters.switchActivated.updateCounterWithFlush();
        evSwitch.updateEventWithFlush(new SwitchEvent(dpid, "activeEqual"));
        addUpdateToQueue(new SwitchUpdate(dpid,
                SwitchUpdateType.ACTIVATED_EQUAL));
        return true;
    }

    /**
     * Called when this controller's role for a switch transitions from equal to
     * master. For 1.0 switches, we internally refer to the role 'slave' as
     * 'equal' - so this transition is equivalent to 'addActivatedMasterSwitch'.
     */
    protected void transitionToMasterSwitch(long dpid) {
        synchronized (multiCacheLock) {
            IOFSwitch sw = activeEqualSwitches.remove(dpid);
            if (sw == null) {
                log.error("Transition to master called on sw {}, but switch "
                        + "was not found in controller-cache", dpid);
                return;
            }
            activeMasterSwitches.put(dpid, sw);
        }
        addUpdateToQueue(new SwitchUpdate(dpid,
                SwitchUpdateType.EQUAL_TO_MASTER));
    }

    /**
     * Called when this controller's role for a switch transitions to equal. For
     * 1.0 switches, we internally refer to the role 'slave' as 'equal'.
     */
    protected void transitionToEqualSwitch(long dpid) {
        synchronized (multiCacheLock) {
            IOFSwitch sw = activeMasterSwitches.remove(dpid);
            if (sw == null) {
                log.error("Transition to equal called on sw {}, but switch "
                        + "was not found in controller-cache", dpid);
                return;
            }
            activeEqualSwitches.put(dpid, sw);
        }
        addUpdateToQueue(new SwitchUpdate(dpid,
                SwitchUpdateType.MASTER_TO_EQUAL));
    }

    /**
     * Clear all state in controller switch maps for a switch that has
     * disconnected from the local controller. Also release control for that
     * switch from the global repository. Notify switch listeners.
     */
    protected void removeConnectedSwitch(long dpid) {
        releaseRegistryControl(dpid);
        connectedSwitches.remove(dpid);
        IOFSwitch sw = activeMasterSwitches.remove(dpid);
        if (sw == null) {
            sw = activeEqualSwitches.remove(dpid);
        }
        if (sw != null) {
            sw.cancelAllStatisticsReplies();
            sw.setConnected(false); // do we need this?
        }
        evSwitch.updateEventWithFlush(new SwitchEvent(dpid, "disconnected"));
        counters.switchDisconnected.updateCounterWithFlush();
        addUpdateToQueue(new SwitchUpdate(dpid, SwitchUpdateType.DISCONNECTED));
    }

    /**
     * Indicates that ports on the given switch have changed. Enqueue a switch
     * update.
     *
     * @param sw
     */
    protected void notifyPortChanged(long dpid, OFPortDesc port,
            PortChangeType changeType) {
        if (port == null || changeType == null) {
            String msg = String.format("Switch port or changetType must not "
                    + "be null in port change notification");
            throw new NullPointerException(msg);
        }
        if (connectedSwitches.get(dpid) == null || getSwitch(dpid) == null) {
            log.warn("Port change update on switch {} not connected or activated "
                    + "... Aborting.", HexString.toHexString(dpid));
            return;
        }

        SwitchUpdate update = new SwitchUpdate(dpid, SwitchUpdateType.PORTCHANGED,
                port, changeType);
        addUpdateToQueue(update);
    }

    // ***************
    // Getters/Setters
    // ***************

    public void setRestApiService(IRestApiService restApi) {
        this.restApi = restApi;
    }

    public void setThreadPoolService(IThreadPoolService tp) {
        this.threadPool = tp;
    }

    public void setMastershipService(IControllerRegistryService serviceImpl) {
        this.registryService = serviceImpl;
    }

    public void setLinkDiscoveryService(ILinkDiscoveryService linkDiscovery) {
        this.linkDiscovery = linkDiscovery;
    }

    public void setDebugCounter(IDebugCounterService debugCounters) {
        this.debugCounters = debugCounters;
    }

    public void setDebugEvent(IDebugEventService debugEvents) {
        this.debugEvents = debugEvents;
    }

    IDebugCounterService getDebugCounter() {
        return this.debugCounters;
    }

    // **********************
    // Role Handling
    // **********************

    /**
     * created by ONOS - works with registry service
     */
    protected class RoleChangeCallback implements ControlChangeCallback {
        @Override
        public void controlChanged(long dpidLong, boolean hasControl) {
            Dpid dpid = new Dpid(dpidLong);
            log.info("Role change callback for switch {}, hasControl {}",
                    dpid, hasControl);

            Role role = null;

            /*
             * issue #229
             * Cannot rely on sw.getRole() as it can be behind due to pending
             * role changes in the queue. Just submit it and late the
             * RoleChanger handle duplicates.
             */

            if (hasControl) {
                role = Role.MASTER;
            } else {
                role = Role.EQUAL; // treat the same as Role.SLAVE
            }

            OFChannelHandler swCh = connectedSwitches.get(dpid.value());
            if (swCh == null) {
                log.warn("Switch {} not found in connected switches", dpid);
                return;
            }

            log.debug("Sending role request {} msg to {}", role, dpid);
            swCh.sendRoleRequest(role, RoleRecvStatus.MATCHED_SET_ROLE);
        }
    }

    public synchronized void submitRegistryRequest(long dpid) {
        OFChannelHandler h = connectedSwitches.get(dpid);
        if (h == null) {
            log.error("Trying to request registry control for switch {} "
                    + "not in connected switches. Aborting.. ",
                    HexString.toHexString(dpid));
            // FIXME shouldn't we immediately return here?
        }
        // Request control of the switch from the global registry
        try {
            h.controlRequested = Boolean.TRUE;
            registryService.requestControl(dpid, new RoleChangeCallback());
        } catch (RegistryException e) {
            log.debug("Registry error: {}", e.getMessage());
            h.controlRequested = Boolean.FALSE;
        }
        if (!h.controlRequested) { // XXX what is being attempted here?
            // yield to allow other thread(s) to release control
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                // Ignore interruptions
            }
            // safer to bounce the switch to reconnect here than proceeding
            // further
            // XXX S why? can't we just try again a little later?
            log.debug("Closing sw:{} because we weren't able to request control " +
                    "successfully" + dpid);
            connectedSwitches.get(dpid).disconnectSwitch();
        }
    }

    public synchronized void releaseRegistryControl(long dpidLong) {
        OFChannelHandler h = connectedSwitches.get(dpidLong);
        if (h == null) {
            log.error("Trying to release registry control for switch {} "
                    + "not in connected switches. Aborting.. ",
                    HexString.toHexString(dpidLong));
            return;
        }
        if (h.controlRequested) {
            registryService.releaseControl(dpidLong);
        }
    }

    // *******************
    // OF Message Handling
    // *******************

    /**
     * Handle and dispatch a message to IOFMessageListeners.
     *
     * We only dispatch messages to listeners if the controller's role is
     * MASTER.
     *
     * @param sw The switch sending the message
     * @param m The message the switch sent
     * @param flContext The floodlight context to use for this message. If null,
     *        a new context will be allocated.
     * @throws IOException
     *
     *         FIXME: this method and the ChannelHandler disagree on which
     *         messages should be dispatched and which shouldn't
     */
    @LogMessageDocs({
            @LogMessageDoc(level = "ERROR",
                    message = "Ignoring PacketIn (Xid = {xid}) because the data" +
                            " field is empty.",
                    explanation = "The switch sent an improperly-formatted PacketIn" +
                            " message",
                    recommendation = LogMessageDoc.CHECK_SWITCH),
            @LogMessageDoc(level = "WARN",
                    message = "Unhandled OF Message: {} from {}",
                    explanation = "The switch sent a message not handled by " +
                            "the controller")
    })
    @SuppressWarnings({"fallthrough", "unchecked"})
    protected void handleMessage(IOFSwitch sw, OFMessage m,
            FloodlightContext bContext)
            throws IOException {
        Ethernet eth = null;
        // FIXME losing port number precision here
        short inport = -1;

        switch (m.getType()) {
        case PACKET_IN:
            OFPacketIn pi = (OFPacketIn) m;
            // log.info("saw packet in from sw {}", sw.getStringId());
            if (pi.getData().length <= 0) {
                log.error("Ignoring PacketIn (Xid = " + pi.getXid() +
                        ") because/*  the data field is empty.");
                return;
            }

            // get incoming port to store in floodlight context
            if (sw.getOFVersion() == OFVersion.OF_10) {
                inport = pi.getInPort().getShortPortNumber();
            } else if (sw.getOFVersion() == OFVersion.OF_13) {
                for (MatchField<?> mf : pi.getMatch().getMatchFields()) {
                    if (mf.id == MatchFields.IN_PORT) {
                        inport = pi.getMatch().get((MatchField<OFPort>) mf)
                                .getShortPortNumber();
                        break;
                    }
                }
                if (inport == -1) {
                    log.error("Match field for incoming port missing in "
                            + "packet-in from sw {}. Ignoring msg",
                            sw.getStringId());
                    return;
                }
            } else {
                // should have been taken care of earlier in handshake
                log.error("OFVersion {} not supported for "
                        + "packet-in from sw {}. Ignoring msg",
                        sw.getOFVersion(), sw.getStringId());
                return;
            }

            // decode enclosed ethernet packet to store in floodlight context
            if (Controller.ALWAYS_DECODE_ETH) {
                eth = new Ethernet();
                eth.deserialize(pi.getData(), 0,
                        pi.getData().length);
            }
            // fall through to default case...

            /*log.debug("Sw:{} packet-in: {}", sw.getStringId(),
            String.format("0x%x", eth.getEtherType()));*/
            if (eth.getEtherType() != (short) EthType.LLDP.getValue())
                log.trace("Sw:{} packet-in: {}", sw.getStringId(), pi);

        default:

            List<IOFMessageListener> listeners = null;

            if (messageListeners.containsKey(m.getType())) {
                listeners = messageListeners.get(m.getType()).
                        getOrderedListeners();
            }
            FloodlightContext bc = null;
            if (listeners != null) {
                // Check if floodlight context is passed from the calling
                // function, if so use that floodlight context, otherwise
                // allocate one
                if (bContext == null) {
                    bc = flcontext_alloc();
                } else {
                    bc = bContext;
                }
                if (eth != null) {
                    IFloodlightProviderService.bcStore.put(bc,
                            IFloodlightProviderService.CONTEXT_PI_PAYLOAD,
                            eth);
                }
                if (inport != -1) {
                    bc.getStorage().put(
                            IFloodlightProviderService.CONTEXT_PI_INPORT,
                            inport);
                }

                // Get the starting time (overall and per-component) of
                // the processing chain for this packet if performance
                // monitoring is turned on

                Command cmd = null;
                for (IOFMessageListener listener : listeners) {
                    if (listener instanceof IOFSwitchFilter) {
                        if (!((IOFSwitchFilter) listener).isInterested(sw)) {
                            continue;
                        }
                    }

                    cmd = listener.receive(sw, m, bc);

                    if (Command.STOP.equals(cmd)) {
                        break;
                    }
                }

            } else {
                log.warn("Unhandled OF Message: {} from {}", m, sw);
            }

            if ((bContext == null) && (bc != null))
                flcontext_free(bc);
        }
    }

    // ***************
    // IFloodlightProviderService
    // ***************

    // FIXME: remove this method
    @Override
    public Map<Long, IOFSwitch> getSwitches() {
        return getMasterSwitches();
    }

    // FIXME: remove this method
    public Map<Long, IOFSwitch> getMasterSwitches() {
        return Collections.unmodifiableMap(activeMasterSwitches);
    }

    @Override
    public Set<Long> getAllSwitchDpids() {
        Set<Long> dpids = new HashSet<Long>();
        dpids.addAll(activeMasterSwitches.keySet());
        dpids.addAll(activeEqualSwitches.keySet());
        return dpids;
    }

    @Override
    public Set<Long> getAllMasterSwitchDpids() {
        Set<Long> dpids = new HashSet<Long>();
        dpids.addAll(activeMasterSwitches.keySet());
        return dpids;
    }

    @Override
    public Set<Long> getAllEqualSwitchDpids() {
        Set<Long> dpids = new HashSet<Long>();
        dpids.addAll(activeEqualSwitches.keySet());
        return dpids;
    }

    @Override
    public IOFSwitch getSwitch(long dpid) {
        IOFSwitch sw = null;
        if ((sw = activeMasterSwitches.get(dpid)) != null)
            return sw;
        if ((sw = activeEqualSwitches.get(dpid)) != null)
            return sw;
        return sw;
    }

    @Override
    public IOFSwitch getMasterSwitch(long dpid) {
        return activeMasterSwitches.get(dpid);
    }

    @Override
    public IOFSwitch getEqualSwitch(long dpid) {
        return activeEqualSwitches.get(dpid);
    }

    @Override
    public synchronized void addOFMessageListener(OFType type,
            IOFMessageListener listener) {
        ListenerDispatcher<OFType, IOFMessageListener> ldd =
                messageListeners.get(type);
        if (ldd == null) {
            ldd = new ListenerDispatcher<OFType, IOFMessageListener>();
            messageListeners.put(type, ldd);
        }
        ldd.addListener(type, listener);
    }

    @Override
    public synchronized void removeOFMessageListener(OFType type,
            IOFMessageListener listener) {
        ListenerDispatcher<OFType, IOFMessageListener> ldd =
                messageListeners.get(type);
        if (ldd != null) {
            ldd.removeListener(listener);
        }
    }

    public void removeOFMessageListeners(OFType type) {
        messageListeners.remove(type);
    }

    private void logListeners() {
        for (Map.Entry<OFType, ListenerDispatcher<OFType, IOFMessageListener>> entry : messageListeners
                .entrySet()) {

            OFType type = entry.getKey();
            ListenerDispatcher<OFType, IOFMessageListener> ldd =
                    entry.getValue();

            StringBuffer sb = new StringBuffer();
            sb.append("OFMessageListeners for ");
            sb.append(type);
            sb.append(": ");
            for (IOFMessageListener l : ldd.getOrderedListeners()) {
                sb.append(l.getName());
                sb.append(",");
            }
            log.debug(sb.toString());
        }
        StringBuffer sl = new StringBuffer();
        sl.append("SwitchUpdate Listeners: ");
        for (IOFSwitchListener swlistener : switchListeners) {
            sl.append(swlistener.getName());
            sl.append(",");
        }
        log.debug(sl.toString());

    }

    @Override
    public void addOFSwitchListener(IOFSwitchListener listener) {
        this.switchListeners.add(listener);
    }

    @Override
    public void removeOFSwitchListener(IOFSwitchListener listener) {
        this.switchListeners.remove(listener);
    }

    @Override
    public Map<OFType, List<IOFMessageListener>> getListeners() {
        Map<OFType, List<IOFMessageListener>> lers =
                new HashMap<OFType, List<IOFMessageListener>>();
        for (Entry<OFType, ListenerDispatcher<OFType, IOFMessageListener>> e : messageListeners
                .entrySet()) {
            lers.put(e.getKey(), e.getValue().getOrderedListeners());
        }
        return Collections.unmodifiableMap(lers);
    }

    /*@Override
    @LogMessageDocs({
            @LogMessageDoc(message = "Failed to inject OFMessage {message} onto " +
                    "a null switch",
                    explanation = "Failed to process a message because the switch " +
                            " is no longer connected."),
            @LogMessageDoc(level = "ERROR",
                    message = "Error reinjecting OFMessage on switch {switch}",
                    explanation = "An I/O error occured while attempting to " +
                            "process an OpenFlow message",
                    recommendation = LogMessageDoc.CHECK_SWITCH)
    })
    public boolean injectOfMessage(IOFSwitch sw, OFMessage msg,
                                   FloodlightContext bc) {
        if (sw == null) {
            log.info("Failed to inject OFMessage {} onto a null switch", msg);
            return false;
        }

        // FIXME: Do we need to be able to inject messages to switches
        // where we're the slave controller (i.e. they're connected but
        // not active)?
        // FIXME: Don't we need synchronization logic here so we're holding
        // the listener read lock when we call handleMessage? After some
        // discussions it sounds like the right thing to do here would be to
        // inject the message as a netty upstream channel event so it goes
        // through the normal netty event processing, including being
        // handled
        if (!activeSwitches.containsKey(sw.getId())) return false;

        try {
            // Pass Floodlight context to the handleMessages()
            handleMessage(sw, msg, bc);
        } catch (IOException e) {
            log.error("Error reinjecting OFMessage on switch {}",
                    HexString.toHexString(sw.getId()));
            return false;
        }
        return true;
    }*/

    // @Override
    // public boolean injectOfMessage(IOFSwitch sw, OFMessage msg) {
    // // call the overloaded version with floodlight context set to null
    // return injectOfMessage(sw, msg, null);
    // }

    // @Override
    // public void handleOutgoingMessage(IOFSwitch sw, OFMessage m,
    // FloodlightContext bc) {
    //
    // List<IOFMessageListener> listeners = null;
    // if (messageListeners.containsKey(m.getType())) {
    // listeners =
    // messageListeners.get(m.getType()).getOrderedListeners();
    // }
    //
    // if (listeners != null) {
    // for (IOFMessageListener listener : listeners) {
    // if (listener instanceof IOFSwitchFilter) {
    // if (!((IOFSwitchFilter) listener).isInterested(sw)) {
    // continue;
    // }
    // }
    // if (Command.STOP.equals(listener.receive(sw, m, bc))) {
    // break;
    // }
    // }
    // }
    // }

    /**
     * Gets an OpenFlow message factory for version 1.0.
     *
     * @return an OpenFlow 1.0 message factory
     */
    public OFFactory getOFMessageFactory_10() {
        return factory10;
    }

    /**
     * Gets an OpenFlow message factory for version 1.3.
     *
     * @return an OpenFlow 1.3 message factory
     */
    public OFFactory getOFMessageFactory_13() {
        return factory13;
    }

    @Override
    public void publishUpdate(IUpdate update) {
        try {
            this.updates.put(update);
        } catch (InterruptedException e) {
            log.error("Failure adding update to queue", e);
        }
    }

    @Override
    public Map<String, String> getControllerNodeIPs() {
        // We return a copy of the mapping so we can guarantee that
        // the mapping return is the same as one that will be (or was)
        // dispatched to IHAListeners
        HashMap<String, String> retval = new HashMap<String, String>();
        synchronized (controllerNodeIPsCache) {
            retval.putAll(controllerNodeIPsCache);
        }
        return retval;
    }

    @Override
    public long getSystemStartTime() {
        return (this.systemStartTime);
    }

    @Override
    public void setAlwaysClearFlowsOnSwAdd(boolean value) {
        this.alwaysClearFlowsOnSwAdd = value;
    }

    @Override
    public OnosInstanceId getOnosInstanceId() {
        return onosInstanceId;
    }

    /**
     * FOR TESTING ONLY. Dispatch all updates in the update queue until queue is
     * empty
     */
    void processUpdateQueueForTesting() {
        while (!updates.isEmpty()) {
            IUpdate update = updates.poll();
            if (update != null)
                update.dispatch();
        }
    }

    // **************
    // Initialization
    // **************

    // XXX S This should probably go away OR it should be edited to handle
    // controller roles per switch! Then it could be a way to
    // deterministically configure a switch to a MASTER controller instance
    /**
     * Sets the initial role based on properties in the config params. It looks
     * for two different properties. If the "role" property is specified then
     * the value should be either "EQUAL", "MASTER", or "SLAVE" and the role of
     * the controller is set to the specified value. If the "role" property is
     * not specified then it looks next for the "role.path" property. In this
     * case the value should be the path to a property file in the file system
     * that contains a property called "floodlight.role" which can be one of the
     * values listed above for the "role" property. The idea behind the
     * "role.path" mechanism is that you have some separate heartbeat and master
     * controller election algorithm that determines the role of the controller.
     * When a role transition happens, it updates the current role in the file
     * specified by the "role.path" file. Then if floodlight restarts for some
     * reason it can get the correct current role of the controller from the
     * file.
     *
     * @param configParams The config params for the FloodlightProvider service
     * @return A valid role if role information is specified in the config
     *         params, otherwise null
     */
    @LogMessageDocs({
            @LogMessageDoc(message = "Controller role set to {role}",
                    explanation = "Setting the initial HA role to "),
            @LogMessageDoc(level = "ERROR",
                    message = "Invalid current role value: {role}",
                    explanation = "An invalid HA role value was read from the " +
                            "properties file",
                    recommendation = LogMessageDoc.CHECK_CONTROLLER)
    })
    protected Role getInitialRole(Map<String, String> configParams) {
        Role role = null;
        String roleString = configParams.get("role");
        FileInputStream fs = null;
        if (roleString == null) {
            String rolePath = configParams.get("rolepath");
            if (rolePath != null) {
                Properties properties = new Properties();
                try {
                    fs = new FileInputStream(rolePath);
                    properties.load(fs);
                    roleString = properties.getProperty("floodlight.role");
                } catch (IOException exc) {
                    // Don't treat it as an error if the file specified by the
                    // rolepath property doesn't exist. This lets us enable the
                    // HA mechanism by just creating/setting the floodlight.role
                    // property in that file without having to modify the
                    // floodlight properties.
                } finally {
                    if (fs != null) {
                        try {
                            fs.close();
                        } catch (IOException e) {
                            log.error("Exception while closing resource ", e);
                        }
                    }
                }
            }
        }

        if (roleString != null) {
            // Canonicalize the string to the form used for the enum constants
            roleString = roleString.trim().toUpperCase();
            try {
                role = Role.valueOf(roleString);
            } catch (IllegalArgumentException exc) {
                log.error("Invalid current role value: {}", roleString);
            }
        }

        log.info("Controller role set to {}", role);

        return role;
    }

    /**
     * Tell controller that we're ready to accept switches loop
     *
     * @throws IOException
     */
    @Override
    @LogMessageDocs({
            @LogMessageDoc(message = "Listening for switch connections on {address}",
                    explanation = "The controller is ready and listening for new" +
                            " switch connections"),
            @LogMessageDoc(message = "Storage exception in controller " +
                    "updates loop; terminating process",
                    explanation = ERROR_DATABASE,
                    recommendation = LogMessageDoc.CHECK_CONTROLLER),
            @LogMessageDoc(level = "ERROR",
                    message = "Exception in controller updates loop",
                    explanation = "Failed to dispatch controller event",
                    recommendation = LogMessageDoc.GENERIC_ACTION)
    })
    public void run() {
        if (log.isDebugEnabled()) {
            logListeners();
        }

        try {
            final ServerBootstrap bootstrap = createServerBootStrap();

            bootstrap.setOption("reuseAddr", true);
            bootstrap.setOption("child.keepAlive", true);
            bootstrap.setOption("child.tcpNoDelay", true);
            bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);

            ChannelPipelineFactory pfact =
                    new OpenflowPipelineFactory(this, null);
            bootstrap.setPipelineFactory(pfact);
            InetSocketAddress sa = new InetSocketAddress(openFlowPort);
            final ChannelGroup cg = new DefaultChannelGroup();
            cg.add(bootstrap.bind(sa));

            log.info("Listening for switch connections on {}", sa);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

        // main loop
        while (true) {
            try {
                IUpdate update = updates.take();
                update.dispatch();
            } catch (InterruptedException e) {
                log.error("Received interrupted exception in updates loop;" +
                        "terminating process");
                terminate();
            } catch (Exception e) {
                log.error("Exception in controller updates loop", e);
            }
        }
    }

    private ServerBootstrap createServerBootStrap() {
        if (workerThreads == 0) {
            return new ServerBootstrap(
                    new NioServerSocketChannelFactory(
                            Executors.newCachedThreadPool(),
                            Executors.newCachedThreadPool()));
        } else {
            return new ServerBootstrap(
                    new NioServerSocketChannelFactory(
                            Executors.newCachedThreadPool(),
                            Executors.newCachedThreadPool(), workerThreads));
        }
    }

    public void setConfigParams(Map<String, String> configParams) {
        String ofPort = configParams.get("openflowport");
        if (ofPort != null) {
            this.openFlowPort = Integer.parseInt(ofPort);
        }
        log.debug("OpenFlow port set to {}", this.openFlowPort);
        String threads = configParams.get("workerthreads");
        if (threads != null) {
            this.workerThreads = Integer.parseInt(threads);
        }
        log.debug("Number of worker threads set to {}", this.workerThreads);
        String controllerId = configParams.get("controllerid");
        if (controllerId != null) {
            this.onosInstanceId = new OnosInstanceId(controllerId);
        } else {
            // Try to get the hostname of the machine and use that for
            // controller ID
            try {
                String hostname = java.net.InetAddress.getLocalHost().getHostName();
                this.onosInstanceId = new OnosInstanceId(hostname);
            } catch (UnknownHostException e) {
                // Can't get hostname, we'll just use the default
            }
        }

        String useOnly10 = configParams.get("useOnly10");
        if (useOnly10 != null && useOnly10.equalsIgnoreCase("true")) {
            OFChannelHandler.useOnly10 = true;
            log.info("Setting controller to only use OpenFlow 1.0");
        }

        log.debug("ControllerId set to {}", this.onosInstanceId);
    }

    /**
     * Initialize internal data structures
     */
    public void init(Map<String, String> configParams) {
        // These data structures are initialized here because other
        // module's startUp() might be called before ours
        this.messageListeners =
                new ConcurrentHashMap<OFType, ListenerDispatcher<OFType,
                IOFMessageListener>>();
        this.switchListeners = new CopyOnWriteArraySet<IOFSwitchListener>();
        this.activeMasterSwitches = new ConcurrentHashMap<Long, IOFSwitch>();
        this.activeEqualSwitches = new ConcurrentHashMap<Long, IOFSwitch>();
        this.connectedSwitches = new ConcurrentHashMap<Long, OFChannelHandler>();
        this.controllerNodeIPsCache = new HashMap<String, String>();
        this.updates = new LinkedBlockingQueue<IUpdate>();

        setConfigParams(configParams);
        this.systemStartTime = System.currentTimeMillis();
        this.counters = new Counters();
        this.multiCacheLock = new Object();

        String option = configParams.get("flushSwitchesOnReconnect");
        if (option != null && option.equalsIgnoreCase("true")) {
            this.setAlwaysClearFlowsOnSwActivate(true);
            log.info("Flush switches on reconnect -- Enabled.");
        } else {
            this.setAlwaysClearFlowsOnSwActivate(false);
            log.info("Flush switches on reconnect -- Disabled");
        }

        option = configParams.get("cpqdUsePipeline13");
        if (option != null && option.equalsIgnoreCase("true")) {
            DriverManager.setConfigForCpqd(true);
            log.info("Using OF1.3 pipeline for the CPqD software switch");
        } else {
            log.info("Using OF1.0 pipeline for the CPqD software switch");
        }

        String disableOvsClassification =
                configParams.get("disableOvsClassification");
        if (disableOvsClassification != null &&
                disableOvsClassification.equalsIgnoreCase("true")) {
            DriverManager.setDisableOvsClassification(true);
            log.info("OVS switches will be classified as default switches");
        }
    }

    /**
     * Startup all of the controller's components
     *
     * @throws FloodlightModuleException
     */
    @LogMessageDoc(message = "Waiting for storage source",
            explanation = "The system database is not yet ready",
            recommendation = "If this message persists, this indicates " +
                    "that the system database has failed to start. " +
                    LogMessageDoc.CHECK_CONTROLLER)
    public void startupComponents() throws FloodlightModuleException {
        try {
            registryService.registerController(onosInstanceId.toString());
        } catch (RegistryException e) {
            log.warn("Registry service error: {}", e.getMessage());
        }

        // Add our REST API
        restApi.addRestletRoutable(new CoreWebRoutable());

        // Startup load monitoring
        if (overload_drop) {
            this.loadmonitor.startMonitoring(
                    this.threadPool.getScheduledExecutor());
        }

        // register counters and events
        try {
            this.counters.createCounters(debugCounters);
        } catch (CounterException e) {
            throw new FloodlightModuleException(e.getMessage());
        }
        registerControllerDebugEvents();
    }

    // **************
    // debugCounter registrations
    // **************

    public static class Counters {
        public static final String prefix = "controller";
        public IDebugCounter setRoleEqual;
        public IDebugCounter setSameRole;
        public IDebugCounter setRoleMaster;
        public IDebugCounter remoteStoreNotification;
        public IDebugCounter invalidPortsChanged;
        public IDebugCounter invalidSwitchActivatedWhileSlave;
        public IDebugCounter invalidStoreEventWhileMaster;
        public IDebugCounter switchDisconnectedWhileSlave;
        public IDebugCounter switchActivated;
        public IDebugCounter errorSameSwitchReactivated; // err
        public IDebugCounter switchWithSameDpidActivated; // warn
        public IDebugCounter newSwitchActivated; // new switch
        public IDebugCounter syncedSwitchActivated;
        public IDebugCounter readyForReconcile;
        public IDebugCounter newSwitchFromStore;
        public IDebugCounter updatedSwitchFromStore;
        public IDebugCounter switchDisconnected;
        public IDebugCounter syncedSwitchRemoved;
        public IDebugCounter unknownSwitchRemovedFromStore;
        public IDebugCounter consolidateStoreRunCount;
        public IDebugCounter consolidateStoreInconsistencies;
        public IDebugCounter storeSyncError;
        public IDebugCounter switchesNotReconnectingToNewMaster;
        public IDebugCounter switchPortChanged;
        public IDebugCounter switchOtherChange;
        public IDebugCounter dispatchMessageWhileSlave;
        public IDebugCounter dispatchMessage; // does this cnt make sense? more
                                              // specific?? per type? count
                                              // stops?
        public IDebugCounter controllerNodeIpsChanged;
        public IDebugCounter messageReceived;
        public IDebugCounter messageInputThrottled;
        public IDebugCounter switchDisconnectReadTimeout;
        public IDebugCounter switchDisconnectHandshakeTimeout;
        public IDebugCounter switchDisconnectIOError;
        public IDebugCounter switchDisconnectParseError;
        public IDebugCounter switchDisconnectSwitchStateException;
        public IDebugCounter rejectedExecutionException;
        public IDebugCounter switchDisconnectOtherException;
        public IDebugCounter switchConnected;
        public IDebugCounter unhandledMessage;
        public IDebugCounter packetInWhileSwitchIsSlave;
        public IDebugCounter epermErrorWhileSwitchIsMaster;
        public IDebugCounter roleNotResentBecauseRolePending;
        public IDebugCounter roleRequestSent;
        public IDebugCounter roleReplyTimeout;
        public IDebugCounter roleReplyReceived; // expected RoleReply received
        public IDebugCounter roleReplyErrorUnsupported;
        public IDebugCounter switchCounterRegistrationFailed;
        public IDebugCounter packetParsingError;

        void createCounters(IDebugCounterService debugCounters) throws CounterException {
            setRoleEqual =
                    debugCounters.registerCounter(
                            prefix, "set-role-equal",
                            "Controller received a role request with role of " +
                                    "EQUAL which is unusual",
                            CounterType.ALWAYS_COUNT);
            setSameRole =
                    debugCounters.registerCounter(
                            prefix, "set-same-role",
                            "Controller received a role request for the same " +
                                    "role the controller already had",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_WARN);

            setRoleMaster =
                    debugCounters.registerCounter(
                            prefix, "set-role-master",
                            "Controller received a role request with role of " +
                                    "MASTER. This counter can be at most 1.",
                            CounterType.ALWAYS_COUNT);

            remoteStoreNotification =
                    debugCounters.registerCounter(
                            prefix, "remote-store-notification",
                            "Received a notification from the sync service " +
                                    "indicating that switch information has changed",
                            CounterType.ALWAYS_COUNT);

            invalidPortsChanged =
                    debugCounters.registerCounter(
                            prefix, "invalid-ports-changed",
                            "Received an unexpected ports changed " +
                                    "notification while the controller was in " +
                                    "SLAVE role.",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_WARN);

            invalidSwitchActivatedWhileSlave =
                    debugCounters.registerCounter(
                            prefix, "invalid-switch-activated-while-slave",
                            "Received an unexpected switchActivated " +
                                    "notification while the controller was in " +
                                    "SLAVE role.",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_WARN);

            invalidStoreEventWhileMaster =
                    debugCounters.registerCounter(
                            prefix, "invalid-store-event-while-master",
                            "Received an unexpected notification from " +
                                    "the sync store while the controller was in " +
                                    "MASTER role.",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_WARN);

            switchDisconnectedWhileSlave =
                    debugCounters.registerCounter(
                            prefix, "switch-disconnected-while-slave",
                            "A switch disconnected and the controller was " +
                                    "in SLAVE role.",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_WARN);

            switchActivated =
                    debugCounters.registerCounter(
                            prefix, "switch-activated",
                            "A switch connected to this controller is now " +
                                    "in MASTER role",
                            CounterType.ALWAYS_COUNT);

            errorSameSwitchReactivated = // err
            debugCounters.registerCounter(
                    prefix, "error-same-switch-reactivated",
                    "A switch that was already in active state " +
                            "was activated again. This indicates a " +
                            "controller defect",
                    CounterType.ALWAYS_COUNT,
                    IDebugCounterService.CTR_MDATA_ERROR);

            switchWithSameDpidActivated = // warn
            debugCounters.registerCounter(
                    prefix, "switch-with-same-dpid-activated",
                    "A switch with the same DPID as another switch " +
                            "connected to the controller. This can be " +
                            "caused by multiple switches configured with " +
                            "the same DPID or by a switch reconnecting very " +
                            "quickly.",
                    CounterType.COUNT_ON_DEMAND,
                    IDebugCounterService.CTR_MDATA_WARN);

            newSwitchActivated = // new switch
            debugCounters.registerCounter(
                    prefix, "new-switch-activated",
                    "A new switch has completed the handshake as " +
                            "MASTER. The switch was not known to any other " +
                            "controller in the cluster",
                    CounterType.ALWAYS_COUNT);
            syncedSwitchActivated =
                    debugCounters.registerCounter(
                            prefix, "synced-switch-activated",
                            "A switch has completed the handshake as " +
                                    "MASTER. The switch was known to another " +
                                    "controller in the cluster",
                            CounterType.ALWAYS_COUNT);

            readyForReconcile =
                    debugCounters.registerCounter(
                            prefix, "ready-for-reconcile",
                            "Controller is ready for flow reconciliation " +
                                    "after Slave to Master transition. Either all " +
                                    "previously known switches are now active " +
                                    "or they have timed out and have been removed." +
                                    "This counter will be 0 or 1.",
                            CounterType.ALWAYS_COUNT);

            newSwitchFromStore =
                    debugCounters.registerCounter(
                            prefix, "new-switch-from-store",
                            "A new switch has connected to another " +
                                    "another controller in the cluster. This " +
                                    "controller instance has received a sync store " +
                                    "notification for it.",
                            CounterType.ALWAYS_COUNT);

            updatedSwitchFromStore =
                    debugCounters.registerCounter(
                            prefix, "updated-switch-from-store",
                            "Information about a switch connected to " +
                                    "another controller instance was updated in " +
                                    "the sync store. This controller instance has " +
                                    "received a notification for it",
                            CounterType.ALWAYS_COUNT);

            switchDisconnected =
                    debugCounters.registerCounter(
                            prefix, "switch-disconnected",
                            "FIXME: switch has disconnected",
                            CounterType.ALWAYS_COUNT);

            syncedSwitchRemoved =
                    debugCounters.registerCounter(
                            prefix, "synced-switch-removed",
                            "A switch connected to another controller " +
                                    "instance has disconnected from the controller " +
                                    "cluster. This controller instance has " +
                                    "received a notification for it",
                            CounterType.ALWAYS_COUNT);

            unknownSwitchRemovedFromStore =
                    debugCounters.registerCounter(
                            prefix, "unknown-switch-removed-from-store",
                            "This controller instances has received a sync " +
                                    "store notification that a switch has " +
                                    "disconnected but this controller instance " +
                                    "did not have the any information about the " +
                                    "switch", // might be less than warning
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_WARN);

            consolidateStoreRunCount =
                    debugCounters.registerCounter(
                            prefix, "consolidate-store-run-count",
                            "This controller has transitioned from SLAVE " +
                                    "to MASTER and waited for switches to reconnect. " +
                                    "The controller has finished waiting and has " +
                                    "reconciled switch entries in the sync store " +
                                    "with live state",
                            CounterType.ALWAYS_COUNT);

            consolidateStoreInconsistencies =
                    debugCounters.registerCounter(
                            prefix, "consolidate-store-inconsistencies",
                            "During switch sync store consolidation: " +
                                    "Number of switches that were in the store " +
                                    "but not otherwise known plus number of " +
                                    "switches that were in the store previously " +
                                    "but are now missing plus number of " +
                                    "connected switches that were absent from " +
                                    "the store although this controller has " +
                                    "written them. A non-zero count " +
                                    "indicates a brief split-brain dual MASTER " +
                                    "situation during fail-over",
                            CounterType.ALWAYS_COUNT);

            storeSyncError =
                    debugCounters.registerCounter(
                            prefix, "store-sync-error",
                            "Number of times a sync store operation failed " +
                                    "due to a store sync exception or an entry in " +
                                    "in the store had invalid data.",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_ERROR);

            switchesNotReconnectingToNewMaster =
                    debugCounters.registerCounter(
                            prefix, "switches-not-reconnecting-to-new-master",
                            "Switches that were connected to another " +
                                    "controller instance in the cluster but that " +
                                    "did not reconnect to this controller after it " +
                                    "transitioned to MASTER", // might be less
                                                              // than warning
                            CounterType.ALWAYS_COUNT);

            switchPortChanged =
                    debugCounters.registerCounter(
                            prefix, "switch-port-changed",
                            "Number of times switch ports have changed",
                            CounterType.ALWAYS_COUNT);
            switchOtherChange =
                    debugCounters.registerCounter(
                            prefix, "switch-other-change",
                            "Number of times other information of a switch " +
                                    "has changed.",
                            CounterType.ALWAYS_COUNT);

            dispatchMessageWhileSlave =
                    debugCounters.registerCounter(
                            prefix, "dispatch-message-while-slave",
                            "Number of times an OF message was received " +
                                    "and supposed to be dispatched but the " +
                                    "controller was in SLAVE role and the message " +
                                    "was not dispatched",
                            CounterType.ALWAYS_COUNT);

            dispatchMessage = // does this cnt make sense? more specific?? per
                              // type? count stops?
            debugCounters.registerCounter(
                    prefix, "dispatch-message",
                    "Number of times an OF message was dispatched " +
                            "to registered modules",
                    CounterType.ALWAYS_COUNT);

            controllerNodeIpsChanged =
                    debugCounters.registerCounter(
                            prefix, "controller-nodes-ips-changed",
                            "IP addresses of controller nodes have changed",
                            CounterType.ALWAYS_COUNT);

            // ------------------------
            // channel handler counters. Factor them out ??
            messageReceived =
                    debugCounters.registerCounter(
                            prefix, "message-received",
                            "Number of OpenFlow messages received. Some of " +
                                    "these might be throttled",
                            CounterType.ALWAYS_COUNT);
            messageInputThrottled =
                    debugCounters.registerCounter(
                            prefix, "message-input-throttled",
                            "Number of OpenFlow messages that were " +
                                    "throttled due to high load from the sender",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_WARN);
            // TODO: more counters in messageReceived ??

            switchDisconnectReadTimeout =
                    debugCounters.registerCounter(
                            prefix, "switch-disconnect-read-timeout",
                            "Number of times a switch was disconnected due " +
                                    "due the switch failing to send OpenFlow " +
                                    "messages or responding to OpenFlow ECHOs",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_ERROR);
            switchDisconnectHandshakeTimeout =
                    debugCounters.registerCounter(
                            prefix, "switch-disconnect-handshake-timeout",
                            "Number of times a switch was disconnected " +
                                    "because it failed to complete the handshake " +
                                    "in time.",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_ERROR);
            switchDisconnectIOError =
                    debugCounters.registerCounter(
                            prefix, "switch-disconnect-io-error",
                            "Number of times a switch was disconnected " +
                                    "due to IO errors on the switch connection.",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_ERROR);
            switchDisconnectParseError =
                    debugCounters.registerCounter(
                            prefix, "switch-disconnect-parse-error",
                            "Number of times a switch was disconnected " +
                                    "because it sent an invalid packet that could " +
                                    "not be parsed",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_ERROR);

            switchDisconnectSwitchStateException =
                    debugCounters.registerCounter(
                            prefix, "switch-disconnect-switch-state-exception",
                            "Number of times a switch was disconnected " +
                                    "because it sent messages that were invalid " +
                                    "given the switch connection's state.",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_ERROR);
            rejectedExecutionException =
                    debugCounters.registerCounter(
                            prefix, "rejected-execution-exception",
                            "TODO",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_ERROR);

            switchDisconnectOtherException =
                    debugCounters.registerCounter(
                            prefix, "switch-disconnect-other-exception",
                            "Number of times a switch was disconnected " +
                                    "due to an exceptional situation not covered " +
                                    "by other counters",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_ERROR);

            switchConnected =
                    debugCounters.registerCounter(
                            prefix, "switch-connected",
                            "Number of times a new switch connection was " +
                                    "established",
                            CounterType.ALWAYS_COUNT);

            unhandledMessage =
                    debugCounters.registerCounter(
                            prefix, "unhandled-message",
                            "Number of times an OpenFlow message was " +
                                    "received that the controller ignored because " +
                                    "it was inapproriate given the switch " +
                                    "connection's state.",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_WARN);
            // might be less than warning

            packetInWhileSwitchIsSlave =
                    debugCounters.registerCounter(
                            prefix, "packet-in-while-switch-is-slave",
                            "Number of times a packet in was received " +
                                    "from a switch that was in SLAVE role. " +
                                    "Possibly inidicates inconsistent roles.",
                            CounterType.ALWAYS_COUNT);
            epermErrorWhileSwitchIsMaster =
                    debugCounters.registerCounter(
                            prefix, "eperm-error-while-switch-is-master",
                            "Number of times a permission error was " +
                                    "received while the switch was in MASTER role. " +
                                    "Possibly inidicates inconsistent roles.",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_WARN);

            roleNotResentBecauseRolePending =
                    debugCounters.registerCounter(
                            prefix, "role-not-resent-because-role-pending",
                            "The controller tried to reestablish a role " +
                                    "with a switch but did not do so because a " +
                                    "previous role request was still pending",
                            CounterType.ALWAYS_COUNT);
            roleRequestSent =
                    debugCounters.registerCounter(
                            prefix, "role-request-sent",
                            "Number of times the controller sent a role " +
                                    "request to a switch.",
                            CounterType.ALWAYS_COUNT);
            roleReplyTimeout =
                    debugCounters.registerCounter(
                            prefix, "role-reply-timeout",
                            "Number of times a role request message did not " +
                                    "receive the expected reply from a switch",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_WARN);

            roleReplyReceived = // expected RoleReply received
            debugCounters.registerCounter(
                    prefix, "role-reply-received",
                    "Number of times the controller received the " +
                            "expected role reply message from a switch",
                    CounterType.ALWAYS_COUNT);

            roleReplyErrorUnsupported =
                    debugCounters.registerCounter(
                            prefix, "role-reply-error-unsupported",
                            "Number of times the controller received an " +
                                    "error from a switch in response to a role " +
                                    "request indicating that the switch does not " +
                                    "support roles.",
                            CounterType.ALWAYS_COUNT);

            switchCounterRegistrationFailed =
                    debugCounters.registerCounter(prefix,
                            "switch-counter-registration-failed",
                            "Number of times the controller failed to " +
                                    "register per-switch debug counters",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_WARN);

            packetParsingError =
                    debugCounters.registerCounter(prefix,
                            "packet-parsing-error",
                            "Number of times the packet parsing " +
                                    "encountered an error",
                            CounterType.ALWAYS_COUNT,
                            IDebugCounterService.CTR_MDATA_ERROR);
        }
    }

    @Override
    public Counters getCounters() {
        return this.counters;
    }

    // **************
    // debugEvent registrations
    // **************

    private void registerControllerDebugEvents() throws FloodlightModuleException {
        if (debugEvents == null) {
            debugEvents = new NullDebugEvent();
        }
        try {
            evSwitch = debugEvents.registerEvent(
                    Counters.prefix, "switchevent",
                    "Switch connected, disconnected or port changed",
                    EventType.ALWAYS_LOG, SwitchEvent.class, 100);
        } catch (MaxEventsRegistered e) {
            throw new FloodlightModuleException("Max events registered", e);
        }
    }

    public class SwitchEvent {
        @EventColumn(name = "dpid", description = EventFieldType.DPID)
        long dpid;

        @EventColumn(name = "reason", description = EventFieldType.STRING)
        String reason;

        public SwitchEvent(long dpid, String reason) {
            this.dpid = dpid;
            this.reason = reason;
        }
    }

    // **************
    // Utility methods
    // **************

    @Override
    public void setAlwaysClearFlowsOnSwActivate(boolean value) {
        // this.alwaysClearFlowsOnSwActivate = value;
        // XXX S need to be a little more careful about this
    }

    @Override
    public Map<String, Long> getMemory() {
        Map<String, Long> m = new HashMap<String, Long>();
        Runtime runtime = Runtime.getRuntime();
        m.put("total", runtime.totalMemory());
        m.put("free", runtime.freeMemory());
        return m;
    }

    @Override
    public Long getUptime() {
        RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
        return rb.getUptime();
    }

    /**
     * Forward to the driver-manager to get an IOFSwitch instance.
     *
     * @param desc
     * @return
     */
    protected IOFSwitch getOFSwitchInstance(OFDescStatsReply desc, OFVersion ofv) {
        return DriverManager.getOFSwitchImpl(desc, ofv);
    }

    protected IThreadPoolService getThreadPoolService() {
        return this.threadPool;
    }

    /**
     * Part of the controller updates framework (see 'run()' method) Use this
     * method to add an IUpdate. A thread-pool will serve the update by
     * dispatching it to all listeners for that update.
     *
     * @param update
     */
    @LogMessageDoc(level = "WARN",
            message = "Failure adding update {} to queue",
            explanation = "The controller tried to add an internal notification" +
                    " to its message queue but the add failed.",
            recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG)
    private void addUpdateToQueue(IUpdate update) {
        try {
            this.updates.put(update);
        } catch (InterruptedException e) {
            // This should never happen
            log.error("Failure adding update {} to queue.", update);
        }
    }

    void flushAll() {
        // Flush all flow-mods/packet-out/stats generated from this "train"
        OFSwitchImplBase.flush_all();
        debugCounters.flushCounters();
        debugEvents.flushEvents();
    }

    /**
     * flcontext_free - Free the context to the current thread
     *
     * @param flcontext
     */
    protected void flcontext_free(FloodlightContext flcontext) {
        flcontext.getStorage().clear();
        flcontext_cache.get().push(flcontext);
    }

    @LogMessageDoc(message = "Calling System.exit",
            explanation = "The controller is terminating")
    private synchronized void terminate() {
        log.info("Calling System.exit");
        System.exit(1);
    }

    // ***************
    // Floodlight context related
    // ***************

    /**
     * flcontext_cache - Keep a thread local stack of contexts
     */
    protected static final ThreadLocal<Stack<FloodlightContext>> flcontext_cache =
            new ThreadLocal<Stack<FloodlightContext>>() {
                @Override
                protected Stack<FloodlightContext> initialValue() {
                    return new Stack<FloodlightContext>();
                }
            };

    /**
     * flcontext_alloc - pop a context off the stack, if required create a new
     * one
     *
     * @return FloodlightContext
     */
    protected static FloodlightContext flcontext_alloc() {
        FloodlightContext flcontext = null;

        if (flcontext_cache.get().empty()) {
            flcontext = new FloodlightContext();
        } else {
            flcontext = flcontext_cache.get().pop();
        }

        return flcontext;
    }

}
