/*
 * Copyright 2014-present Open Networking Foundation
 *
 * 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 org.onosproject.provider.of.device.impl;

import com.google.common.base.Strings;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import org.onlab.packet.ChassisId;
import org.onlab.util.Frequency;
import org.onlab.util.Spectrum;
import org.onosproject.cfg.ComponentConfigService;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.ChannelSpacing;
import org.onosproject.net.CltSignalType;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.DefaultAnnotations.Builder;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.GridType;
import org.onosproject.net.MastershipRole;
import org.onosproject.net.OchSignal;
import org.onosproject.net.OduSignalType;
import org.onosproject.net.OtuSignalType;
import org.onosproject.net.Port;
import org.onosproject.net.Port.Type;
import org.onosproject.net.PortNumber;
import org.onosproject.net.SparseAnnotations;
import org.onosproject.net.behaviour.LambdaQuery;
import org.onosproject.net.device.DefaultDeviceDescription;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.DefaultPortStatistics;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceProvider;
import org.onosproject.net.device.DeviceProviderRegistry;
import org.onosproject.net.device.DeviceProviderService;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
import org.onosproject.net.driver.Driver;
import org.onosproject.net.driver.DriverHandler;
import org.onosproject.net.driver.DriverService;
import org.onosproject.net.driver.HandlerBehaviour;
import org.onosproject.net.provider.AbstractProvider;
import org.onosproject.net.provider.ProviderId;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.OpenFlowController;
import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.OpenFlowOpticalSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitchListener;
import org.onosproject.openflow.controller.PortDescPropertyType;
import org.onosproject.openflow.controller.RoleState;
import org.osgi.service.component.ComponentContext;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Modified;
import org.osgi.service.component.annotations.Reference;
import org.osgi.service.component.annotations.ReferenceCardinality;
import org.projectfloodlight.openflow.protocol.OFCalientPortDescProp;
import org.projectfloodlight.openflow.protocol.OFCalientPortDescPropOptical;
import org.projectfloodlight.openflow.protocol.OFCalientPortDescStatsEntry;
import org.projectfloodlight.openflow.protocol.OFCapabilities;
import org.projectfloodlight.openflow.protocol.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFErrorType;
import org.projectfloodlight.openflow.protocol.OFExpPort;
import org.projectfloodlight.openflow.protocol.OFExpPortDescPropOpticalTransport;
import org.projectfloodlight.openflow.protocol.OFExpPortOpticalTransportLayerEntry;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFObject;
import org.projectfloodlight.openflow.protocol.OFPortConfig;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortDescProp;
import org.projectfloodlight.openflow.protocol.OFPortDescPropEthernet;
import org.projectfloodlight.openflow.protocol.OFPortDescPropOptical;
import org.projectfloodlight.openflow.protocol.OFPortDescPropOpticalTransport;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsRequest;
import org.projectfloodlight.openflow.protocol.OFPortFeatures;
import org.projectfloodlight.openflow.protocol.OFPortMod;
import org.projectfloodlight.openflow.protocol.OFPortOptical;
import org.projectfloodlight.openflow.protocol.OFPortOpticalTransportLayerClass;
import org.projectfloodlight.openflow.protocol.OFPortOpticalTransportSignalType;
import org.projectfloodlight.openflow.protocol.OFPortReason;
import org.projectfloodlight.openflow.protocol.OFPortState;
import org.projectfloodlight.openflow.protocol.OFPortStatsEntry;
import org.projectfloodlight.openflow.protocol.OFPortStatsPropOptical;
import org.projectfloodlight.openflow.protocol.OFPortStatsReply;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.projectfloodlight.openflow.protocol.OFStatsReply;
import org.projectfloodlight.openflow.protocol.OFStatsReplyFlags;
import org.projectfloodlight.openflow.protocol.OFStatsType;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.protocol.ver14.OFOpticalPortFeaturesSerializerVer14;
import org.projectfloodlight.openflow.protocol.ver14.OFPortStatsOpticalFlagsSerializerVer14;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.PortSpeed;
import org.slf4j.Logger;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Dictionary;
import java.util.EnumSet;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Properties;
import java.util.Set;
import java.util.Timer;

import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Strings.isNullOrEmpty;
import static org.onlab.util.Tools.get;
import static org.onosproject.net.DeviceId.deviceId;
import static org.onosproject.net.Port.Type.COPPER;
import static org.onosproject.net.Port.Type.FIBER;
import static org.onosproject.net.optical.device.OchPortHelper.ochPortDescription;
import static org.onosproject.net.optical.device.OduCltPortHelper.oduCltPortDescription;
import static org.onosproject.net.optical.device.OmsPortHelper.omsPortDescription;
import static org.onosproject.net.optical.device.OtuPortHelper.otuPortDescription;
import static org.onosproject.openflow.controller.Dpid.dpid;
import static org.onosproject.openflow.controller.Dpid.uri;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Provider which uses an OpenFlow controller to detect network
 * infrastructure devices.
 */
@Component(immediate = true)
public class OpenFlowDeviceProvider extends AbstractProvider implements DeviceProvider {

    private static final Logger LOG = getLogger(OpenFlowDeviceProvider.class);

    // TODO Some duplicate with one defined in OpticalAnnotations
    // slice out optical specific handling and consolidate.
    /**
     * Annotation key for minimum frequency in Hz.
     * Value is expected to be an integer.
     */
    public static final String AK_MIN_FREQ_HZ = "minFrequency";

    /**
     * Annotation key for minimum lambda in nm.
     * Value is expected to be an integer.
     */
    public static final String AK_MIN_LMDA_NM = "minLambda";

    /**
     * Annotation key for maximum frequency in Hz.
     * Value is expected be an integer.
     */
    public static final String AK_MAX_FREQ_HZ = "maxFrequency";

    /**
     * Annotation key for maximum lambda in nm.
     * Value is expected be an integer.
     */
    public static final String AK_MAX_LMDA_NM = "maxLambda";

    /**
     * Annotation key for grid frequency in Hz.
     * Value is expected to be an integer.
     */
    public static final String AK_GRID_HZ = "grid";

    /**
     * Annotation key for grid lambda in nm.
     * Value is expected to be an integer.
     */
    public static final String AK_GRID_LMDA_NM = "gridLambda";

    /**
     * Annotation key for minimum frequency in Hz.
     * Value is expected to be an integer.
     */
    public static final String AK_TX_MIN_FREQ_HZ = "txMinFrequency";

    /**
     * Annotation key for minimum lambda in nm.
     * Value is expected to be an integer.
     */
    public static final String AK_TX_MIN_LMDA_NM = "txMinLambda";

    /**
     * Annotation key for maximum frequency in Hz.
     * Value is expected be an integer.
     */
    public static final String AK_TX_MAX_FREQ_HZ = "txMaxFrequency";

    /**
     * Annotation key for maximum lambda in nm.
     * Value is expected be an integer.
     */
    public static final String AK_TX_MAX_LMDA_NM = "txMaxLambda";

    /**
     * Annotation key for grid frequency in Hz.
     * Value is expected to be an integer.
     */
    public static final String AK_TX_GRID_HZ = "txGrid";

    /**
     * Annotation key for grid lambda in nm.
     * Value is expected to be an integer.
     */
    public static final String AK_TX_GRID_LMDA_NM = "txGridLambda";

    /**
     * Annotation key for minimum frequency in Hz.
     * Value is expected to be an integer.
     */
    public static final String AK_RX_MIN_FREQ_HZ = "rxMinFrequency";

    /**
     * Annotation key for minimum lambda in nm.
     * Value is expected to be an integer.
     */
    public static final String AK_RX_MIN_LMDA_NM = "rxMinLambda";

    /**
     * Annotation key for maximum frequency in Hz.
     * Value is expected be an integer.
     */
    public static final String AK_RX_MAX_FREQ_HZ = "rxMaxFrequency";

    /**
     * Annotation key for maximum lambda in nm.
     * Value is expected be an integer.
     */
    public static final String AK_RX_MAX_LMDA_NM = "rxMaxLambda";

    /**
     * Annotation key for grid frequency in Hz.
     * Value is expected to be an integer.
     */
    public static final String AK_RX_GRID_HZ = "rxGrid";

    /**
     * Annotation key for grid lambda in nm.
     * Value is expected to be an integer.
     */
    public static final String AK_RX_GRID_LMDA_NM = "rxGridLambda";

    /**
     * Annotation key for indicating frequency must be used instead of
     * wavelength for port tuning.
     * Value is expected to be "enabled" or "disabled"
     */
    public static final String AK_USE_FREQ_FEATURE = "useFreqFeature";

    /**
     * Annotation key for minimum transmit power in dBm*10.
     * Value is expected to be an integer.
     */
    public static final String AK_TX_PWR_MIN = "txPowerMin";

    /**
     * Annotation key for maximum transmit power in dBm*10.
     * Value is expected to be an integer.
     */
    public static final String AK_TX_PWR_MAX = "txPowerMax";



    // Port Stats annotations

    /**
     * Annotation key for transmit frequency in Hz.
     * Value is expected be an integer.
     */
    public static final String AK_TX_FREQ_HZ = "txFrequency";

    /**
     * Annotation key for transmit lambda in nm.
     * Value is expected be an integer.
     */
    public static final String AK_TX_LMDA_NM = "txLambda";

    /**
     * Annotation key for transmit offset frequency in Hz.
     * Value is expected be an integer.
     */
    public static final String AK_TX_OFFSET_HZ = "txOffset";

    /**
     * Annotation key for transmit offset in nm.
     * Value is expected be an integer.
     */
    public static final String AK_TX_OFFSET_LMDA_NM = "txOffsetLambda";

    /**
     * Annotation key for transmit grid spacing frequency in Hz.
     * Value is expected be an integer.
     */
    public static final String AK_TX_GRID_SPAN_HZ = "txGridSpan";

    /**
     * Annotation key for transmit grid spacing lambda in nm.
     * Value is expected be an integer.
     */
    public static final String AK_TX_GRID_SPAN_LMDA_NM = "txGridSpanLambda";

    /**
     * Annotation key for receive frequency in Hz.
     * Value is expected be an integer.
     */
    public static final String AK_RX_FREQ_HZ = "rxFrequency";

    /**
     * Annotation key for receive lambda in nm.
     * Value is expected be an integer.
     */
    public static final String AK_RX_LMDA_NM = "rxLambda";

    /**
     * Annotation key for receive offset frequency in Hz.
     * Value is expected be an integer.
     */
    public static final String AK_RX_OFFSET_HZ = "rxOffset";

    /**
     * Annotation key for receive offset lambda in nm.
     * Value is expected be an integer.
     */
    public static final String AK_RX_OFFSET_LMDA_NM = "rxOffsetLambda";

    /**
     * Annotation key for receive grid spacing frequency in Hz.
     * Value is expected be an integer.
     */
    public static final String AK_RX_GRID_SPAN_HZ = "rxGridSpan";

    /**
     * Annotation key for receive grid spacing lambda in nm.
     * Value is expected be an integer.
     */
    public static final String AK_RX_GRID_SPAN_LMDA_NM = "rxGridSpanLambda";

   /**
     * Annotation key for transmit power in dBm*10.
     * Value is expected to be an integer.
     */
    public static final String AK_TX_PWR = "txPower";

    /**
     * Annotation key for receive power feature.
     * Value is expected to be "enabled" or "disabled"
     */
    public static final String AK_RX_PWR_FEATURE = "rxPwrFeature";

   /**
     * Annotation key for receive power in dBm*10.
     * Value is expected to be an integer.
     */
    public static final String AK_RX_PWR = "rxPower";

   /**
     * Annotation key for transmit bias feature.
     * Value is expected to be "enabled" or "disabled"
     */
    public static final String AK_TX_BIAS_FEATURE = "txBiasFeature";

   /**
     * Annotation key for transmit bias current in mA*10.
     * Value is expected to be an integer.
     */
    public static final String AK_BIAS_CURRENT = "biasCurrent";

   /**
     * Annotation key for transmit temperature feature.
     * Value is expected to be "enabled" or "disabled"
     */
    public static final String AK_TX_TEMP_FEATURE = "txTempFeature";

   /**
     * Annotation key for transmit laser temperature in C*10.
     * Value is expected to be an integer.
     */
    public static final String AK_TEMPERATURE = "temperature";


    // Common feature annotations

    /**
     * Annotation key for transmit tune feature.
     * Value is expected to be "enabled" or "disabled"
     */
    public static final String AK_TX_TUNE_FEATURE = "txTuneFeature";

    /**
     * Annotation key for receive tune feature.
     * Value is expected to be "enabled" or "disabled"
     */
    public static final String AK_RX_TUNE_FEATURE = "rxTuneFeature";

    /**
     * Annotation key for transmit power feature.
     * Value is expected to be "enabled" or "disabled"
     */
    public static final String AK_TX_PWR_FEATURE = "txPwrFeature";


    //TODO consider renaming KBPS and MBPS (as they are used to convert by division)
    private static final long KBPS = 1_000;
    private static final long MBPS = 1_000L * 1_000L;
    private static final Frequency FREQ50 = Frequency.ofGHz(50);
    private static final Frequency FREQ191_7 = Frequency.ofGHz(191_700);
    private static final Frequency FREQ4_4 = Frequency.ofGHz(4_400);

    private static final long C = 299792458; // speed of light in m/s
    public static final String SCHEME = "of";

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected DeviceProviderRegistry providerRegistry;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected DeviceService deviceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected OpenFlowController controller;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected ComponentConfigService cfgService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY)
    protected DriverService driverService;

    private DeviceProviderService providerService;

    private final InternalDeviceProvider listener = new InternalDeviceProvider();

    private static final String POLL_PROP_NAME = "portStatsPollFrequency";
    private static final int POLL_INTERVAL = 5;
    //@Property(name = POLL_PROP_NAME, intValue = POLL_INTERVAL,
    //label = "Frequency (in seconds) for polling switch Port statistics")
    private int portStatsPollFrequency = POLL_INTERVAL;

    private static final String PROP_FREQ = "propertyFrequency";
    private static final boolean DEFAULT_PROP_FREQ = true;
    //@Property(name = PROP_FREQ, boolValue = DEFAULT_PROP_FREQ,
    //label = "It indicates frequency must be used instead of wavelength for port tuning.")
    private static boolean propFreq = DEFAULT_PROP_FREQ;

    private final Timer timer = new Timer("onos-openflow-portstats-collector");

    private Map<Dpid, PortStatsCollector> collectors = Maps.newConcurrentMap();

    /**
     * Creates an OpenFlow device provider.
     */
    public OpenFlowDeviceProvider() {
        super(new ProviderId(SCHEME, "org.onosproject.provider.openflow"));
    }

    @Activate
    public void activate(ComponentContext context) {
        cfgService.registerProperties(getClass());
        providerService = providerRegistry.register(this);
        controller.addListener(listener);
        controller.addEventListener(listener);

        modified(context);

        connectInitialDevices();
        LOG.info("Started");
    }

    @Deactivate
    public void deactivate(ComponentContext context) {
        cfgService.unregisterProperties(getClass(), false);
        listener.disable();
        controller.removeListener(listener);
        providerRegistry.unregister(this);
        collectors.values().forEach(PortStatsCollector::stop);
        collectors.clear();
        providerService = null;
        LOG.info("Stopped");
    }

    @Modified
    public void modified(ComponentContext context) {
        Dictionary<?, ?> properties = context != null ? context.getProperties() : new Properties();
        int newPortStatsPollFrequency;
        try {
            String s = get(properties, POLL_PROP_NAME);
            newPortStatsPollFrequency = isNullOrEmpty(s) ? portStatsPollFrequency : Integer.parseInt(s.trim());

        } catch (NumberFormatException | ClassCastException e) {
            newPortStatsPollFrequency = portStatsPollFrequency;
        }

        if (newPortStatsPollFrequency != portStatsPollFrequency) {
            portStatsPollFrequency = newPortStatsPollFrequency;
            collectors.values().forEach(psc -> psc.adjustPollInterval(portStatsPollFrequency));
        }

        LOG.info("Settings: portStatsPollFrequency={}", portStatsPollFrequency);
    }

    private void connectInitialDevices() {
        for (OpenFlowSwitch sw : controller.getSwitches()) {
            try {
                listener.switchAdded(new Dpid(sw.getId()));
            } catch (Exception e) {
                LOG.warn("Failed initially adding {} : {}", sw.getStringId(), e.getMessage());
                LOG.debug("Error details:", e);
                // disconnect to trigger switch-add later
                sw.disconnectSwitch();
            }
        }
    }

    @Override
    public boolean isReachable(DeviceId deviceId) {
        OpenFlowSwitch sw = controller.getSwitch(dpid(deviceId.uri()));
        return sw != null && sw.isConnected();
    }

    @Override
    public void triggerProbe(DeviceId deviceId) {
        LOG.debug("Triggering probe on device {}", deviceId);

        final Dpid dpid = dpid(deviceId.uri());
        OpenFlowSwitch sw = controller.getSwitch(dpid);
        if (sw == null || !sw.isConnected()) {
            LOG.error("Failed to probe device {} on sw={}", deviceId, sw);
            providerService.deviceDisconnected(deviceId);
            return;
        } else {
            LOG.trace("Confirmed device {} connection", deviceId);
        }

        // Prompt an update of port information. We can use any XID for this.
        OFFactory fact = sw.factory();
        switch (fact.getVersion()) {
            case OF_10:
                sw.sendMsg(fact.buildFeaturesRequest().setXid(0).build());
                break;
            case OF_13:
            case OF_14:
            case OF_15:
                sw.sendMsg(fact.buildPortDescStatsRequest().setXid(0).build());
                break;
            default:
                LOG.warn("Unhandled protocol version");
        }
    }

    @Override
    public void roleChanged(DeviceId deviceId, MastershipRole newRole) {
        switch (newRole) {
            case MASTER:
                controller.setRole(dpid(deviceId.uri()), RoleState.MASTER);
                break;
            case STANDBY:
                controller.setRole(dpid(deviceId.uri()), RoleState.EQUAL);
                break;
            case NONE:
                controller.setRole(dpid(deviceId.uri()), RoleState.SLAVE);
                break;
            default:
                LOG.error("Unknown Mastership state : {}", newRole);

        }
        LOG.debug("Accepting mastership role change to {} for device {}", newRole, deviceId);
    }

    @Override
    public void changePortState(DeviceId deviceId, PortNumber portNumber,
                                boolean enable) {
        final Dpid dpid = dpid(deviceId.uri());
        OpenFlowSwitch sw = controller.getSwitch(dpid);
        if (sw == null || !sw.isConnected()) {
            LOG.error("Failed to change portState on device {}", deviceId);
            return;
        }
        OFPortMod.Builder pmb = sw.factory().buildPortMod();
        OFPort port = OFPort.of((int) portNumber.toLong());
        pmb.setPortNo(port);
        Set<OFPortConfig> portConfig = EnumSet.noneOf(OFPortConfig.class);
        if (!enable) {
            portConfig.add(OFPortConfig.PORT_DOWN);
        }
        pmb.setConfig(portConfig);
        Set<OFPortConfig> portMask = EnumSet.noneOf(OFPortConfig.class);
        portMask.add(OFPortConfig.PORT_DOWN);
        pmb.setMask(portMask);
        pmb.setAdvertise(0x0);
        for (OFPortDesc pd : sw.getPorts()) {
            if (pd.getPortNo().equals(port)) {
                pmb.setHwAddr(pd.getHwAddr());
                break;
            }
        }
        sw.sendMsg(Collections.singletonList(pmb.build()));
    }

    @Override
    public void triggerDisconnect(DeviceId deviceId) {
        Dpid dpid = dpid(deviceId.uri());
        OpenFlowSwitch sw = controller.getSwitch(dpid);
        if (sw != null) {
            LOG.debug("Forcing disconnect for device {}", deviceId);
            // TODO: Further consolidate clean-up on device disconnect
            listener.switchRemoved(dpid);
            sw.disconnectSwitch();
        }
    }

    private void pushPortMetrics(Dpid dpid, List<OFPortStatsEntry> portStatsEntries) {
        DeviceId deviceId = DeviceId.deviceId(Dpid.uri(dpid));
        Collection<PortStatistics> stats =
                buildPortStatistics(deviceId, ImmutableList.copyOf(portStatsEntries));
        providerService.updatePortStatistics(deviceId, stats);
    }

    private static String lambdaToAnnotationHz(long lambda) {
        // ref. OF1.5: wavelength (lambda) as nm * 100

        // f = c / λ
        // (m/s) * (nm/m) / (nm * 100) * 100
        // annotations is in Hz
        return Long.toString(lambda == 0 ? lambda : (C * 1_000_000_000 / lambda * 100));
    }

    private static String mhzToAnnotationNm(long freqMhz) {
        // λ = c / f
        // (m/s) * (nm/m) / (1000000 * 1/s)
        // annotations is in nm
        return Long.toString(freqMhz == 0 ? freqMhz : (C * 1_000_000_000 / Frequency.ofMHz(freqMhz).asHz()));
    }


    private static String mhzToAnnotation(long freqMhz) {
        return Long.toString(Frequency.ofMHz(freqMhz).asHz());
    }

    private static String freqLmdaToAnnotation(long freqLmda, boolean useFreq) {
        if (useFreq) {
            if (propFreq) {
                mhzToAnnotation(freqLmda);
            } else {
                mhzToAnnotationNm(freqLmda);
            }
        } else if (propFreq) {
            lambdaToAnnotationHz(freqLmda);
        }
        return Double.toString(freqLmda / 100.0);
    }

    private Collection<PortStatistics> buildPortStatistics(DeviceId deviceId,
                                                           List<OFPortStatsEntry> entries) {
        HashSet<PortStatistics> stats = Sets.newHashSet();
        final Dpid dpid = dpid(deviceId.uri());
        OpenFlowSwitch sw = controller.getSwitch(dpid);

        for (OFPortStatsEntry entry : entries) {
            try {
                if (entry == null || entry.getPortNo() == null || entry.getPortNo().getPortNumber() < 0) {
                    continue;
                }
                DefaultAnnotations.Builder annotations = DefaultAnnotations.builder();
                boolean propSupported = entry.getVersion().getWireVersion() >= OFVersion.OF_14.getWireVersion();
                Optional<OFPortStatsPropOptical> optical = propSupported ?
                    entry.getProperties().stream()
                    .filter(OFPortStatsPropOptical.class::isInstance)
                    .map(OFPortStatsPropOptical.class::cast)
                    .findAny() : Optional.empty();
                if (optical.isPresent()) {
                    long flags = optical.get().getFlags();

                    boolean useFreq = false;
                    for (OFPortDesc pd : sw.getPorts()) {
                        if (pd.getPortNo().equals(entry.getPortNo())) {
                            for (OFPortDescProp prop : pd.getProperties()) {
                                if (prop instanceof OFPortDescPropOptical) {
                                    OFPortDescPropOptical oprop = (OFPortDescPropOptical) prop;
                                    long supported = oprop.getSupported();
                                    int useFreqVal = OFOpticalPortFeaturesSerializerVer14.USE_FREQ_VAL;
                                    if ((supported & useFreqVal) != 0) {
                                        useFreq = true;
                                        break;
                                    }
                                }
                            }
                        }
                    }

                    int txTune = OFPortStatsOpticalFlagsSerializerVer14.TX_TUNE_VAL;
                    long txFreq = optical.get().getTxFreqLmda();
                    long txOffset = optical.get().getTxOffset();
                    long txGridSpan = optical.get().getTxGridSpan();
                    annotations.set(AK_TX_TUNE_FEATURE, ((flags & txTune) != 0) ? "enabled" : "disabled");
                    annotations.set(propFreq ? AK_TX_FREQ_HZ : AK_TX_LMDA_NM,
                                    freqLmdaToAnnotation(txFreq, useFreq));
                    annotations.set(propFreq ? AK_TX_OFFSET_HZ : AK_TX_OFFSET_LMDA_NM,
                                    freqLmdaToAnnotation(txOffset, useFreq));
                    annotations.set(propFreq ? AK_TX_GRID_SPAN_HZ : AK_TX_GRID_SPAN_LMDA_NM,
                                    freqLmdaToAnnotation(txGridSpan, useFreq));

                    int rxTune = OFPortStatsOpticalFlagsSerializerVer14.RX_TUNE_VAL;
                    long rxFreq = optical.get().getRxFreqLmda();
                    long rxOffset = optical.get().getRxOffset();
                    long rxGridSpan = optical.get().getRxGridSpan();
                    annotations.set(AK_RX_TUNE_FEATURE, ((flags & rxTune) != 0) ? "enabled" : "disabled");
                    annotations.set(propFreq ? AK_RX_FREQ_HZ : AK_RX_LMDA_NM,
                                    freqLmdaToAnnotation(rxFreq, useFreq));
                    annotations.set(propFreq ? AK_RX_OFFSET_HZ : AK_RX_OFFSET_LMDA_NM,
                                    freqLmdaToAnnotation(rxOffset, useFreq));
                    annotations.set(propFreq ? AK_RX_GRID_SPAN_HZ : AK_RX_GRID_SPAN_LMDA_NM,
                                    freqLmdaToAnnotation(rxGridSpan, useFreq));

                    int txPwrVal = OFPortStatsOpticalFlagsSerializerVer14.TX_PWR_VAL;
                    int txPwr = optical.get().getTxPwr();
                    annotations.set(AK_TX_PWR_FEATURE, ((flags & txPwrVal) != 0) ? "enabled" : "disabled");
                    annotations.set(AK_TX_PWR, Integer.toString(txPwr));

                    int rxPwrVal = OFPortStatsOpticalFlagsSerializerVer14.RX_PWR_VAL;
                    int rxPwr = optical.get().getRxPwr();
                    annotations.set(AK_RX_PWR_FEATURE, ((flags & rxPwrVal) != 0) ? "enabled" : "disabled");
                    annotations.set(AK_RX_PWR, Integer.toString(rxPwr));

                    int txBias = OFPortStatsOpticalFlagsSerializerVer14.TX_BIAS_VAL;
                    int biasCurrent = optical.get().getBiasCurrent();
                    annotations.set(AK_TX_BIAS_FEATURE, ((flags & txBias) != 0) ? "enabled" : "disabled");
                    annotations.set(AK_BIAS_CURRENT, Integer.toString(biasCurrent));

                    int txTemp = OFPortStatsOpticalFlagsSerializerVer14.TX_TEMP_VAL;
                    int temperature = optical.get().getTemperature();
                    annotations.set(AK_TX_TEMP_FEATURE, ((flags & txTemp) != 0) ? "enabled" : "disabled");
                    annotations.set(AK_TEMPERATURE, Integer.toString(temperature));
                }
                DefaultPortStatistics.Builder builder = DefaultPortStatistics.builder();
                DefaultPortStatistics stat = builder.setDeviceId(deviceId)
                        .setPort(entry.getPortNo().getPortNumber())
                        .setPacketsReceived(entry.getRxPackets().getValue())
                        .setPacketsSent(entry.getTxPackets().getValue())
                        .setBytesReceived(entry.getRxBytes().getValue())
                        .setBytesSent(entry.getTxBytes().getValue())
                        .setPacketsRxDropped(entry.getRxDropped().getValue())
                        .setPacketsTxDropped(entry.getTxDropped().getValue())
                        .setPacketsRxErrors(entry.getRxErrors().getValue())
                        .setPacketsTxErrors(entry.getTxErrors().getValue())
                        .setDurationSec(entry.getVersion() == OFVersion.OF_10 ? 0 : entry.getDurationSec())
                        .setDurationNano(entry.getVersion() == OFVersion.OF_10 ? 0 : entry.getDurationNsec())
                        .setAnnotations(annotations.build())
                        .build();

                stats.add(stat);
            } catch (Exception e) {
                LOG.warn("Unable to process port stats", e);
            }
        }

        return Collections.unmodifiableSet(stats);
    }

    private class InternalDeviceProvider implements OpenFlowSwitchListener, OpenFlowEventListener {

        private HashMap<Dpid, List<OFPortStatsEntry>> portStatsReplies = new HashMap<>();
        private boolean isDisabled = false;

        @Override
        public void switchAdded(Dpid dpid) {
            if (providerService == null) {
                return;
            }
            DeviceId did = deviceId(uri(dpid));
            OpenFlowSwitch sw = controller.getSwitch(dpid);
            if (sw == null) {
                LOG.error("Switch {} is not found", dpid);
                return;
            }

            ChassisId cId = new ChassisId(dpid.value());

            DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
                    .set(AnnotationKeys.PROTOCOL, sw.factory().getVersion().toString())
                    .set(AnnotationKeys.CHANNEL_ID, sw.channelId())
                    .set(AnnotationKeys.MANAGEMENT_ADDRESS, sw.channelId().split(":")[0]);

            // FIXME following ignores driver specified by name
            Driver driver = driverService.getDriver(sw.manufacturerDescription(),
                    sw.hardwareDescription(),
                    sw.softwareDescription());
            // FIXME: The following breaks the STC tests and will require to be revisited.
//            if (driver != null) {
//                annotationsBuilder.set(AnnotationKeys.DRIVER, driver.name());
//            }

            SparseAnnotations annotations = annotationsBuilder.build();

            DeviceDescription description =
                    new DefaultDeviceDescription(did.uri(), sw.deviceType(),
                                                 sw.manufacturerDescription(),
                                                 sw.hardwareDescription(),
                                                 sw.softwareDescription(),
                                                 sw.serialNumber(),
                                                 cId, annotations);
            providerService.deviceConnected(did, description);
            providerService.updatePorts(did, buildPortDescriptions(sw));
            //sends port description stats request again if OF version supports
            if (sw.features().getVersion().compareTo(OFVersion.OF_13) >= 0) {
                sendPortDescStatsRequest(sw);
            }

            if (sw.features().getCapabilities().contains(OFCapabilities.PORT_STATS)) {
                PortStatsCollector psc = new PortStatsCollector(timer, sw, portStatsPollFrequency);
                stopCollectorIfNeeded(collectors.put(dpid, psc));
                psc.start();
            }

            //figure out race condition for collectors.remove() and collectors.put()
            if (controller.getSwitch(dpid) == null) {
                switchRemoved(dpid);
            }
        }

        /**
         * Sends port description statistic request to switch if supported.
         */
        private void sendPortDescStatsRequest(OpenFlowSwitch sw) {
            if (sw == null) {
                return;
            }
            OFPortDescStatsRequest descStatsRequest = sw.factory().buildPortDescStatsRequest()
                    .build();
            sw.sendMsg(descStatsRequest);
        }

        private void stopCollectorIfNeeded(PortStatsCollector collector) {
            if (collector != null) {
                collector.stop();
            }
        }

        @Override
        public void switchRemoved(Dpid dpid) {
            stopCollectorIfNeeded(collectors.remove(dpid));
            if (providerService == null) {
                return;
            }
            providerService.deviceDisconnected(deviceId(uri(dpid)));
        }

        @Override
        public void switchChanged(Dpid dpid) {
            LOG.debug("switchChanged({})", dpid);
            if (providerService == null) {
                return;
            }
            DeviceId did = deviceId(uri(dpid));
            OpenFlowSwitch sw = controller.getSwitch(dpid);
            if (sw == null) {
                LOG.error("Switch {} is not found", dpid);
                return;
            }
            final List<PortDescription> ports = buildPortDescriptions(sw);
            LOG.debug("switchChanged({}) {}", did, ports);
            providerService.updatePorts(did, ports);
        }

        @Override
        public void portChanged(Dpid dpid, OFPortStatus status) {
            LOG.debug("portChanged({},{})", dpid, status);
            PortDescription portDescription = buildPortDescription(status);
            if (status.getReason() != OFPortReason.DELETE) {
                providerService.portStatusChanged(deviceId(uri(dpid)), portDescription);
            } else {
                providerService.deletePort(deviceId(uri(dpid)), portDescription);
            }
        }

        @Override
        public void receivedRoleReply(Dpid dpid, RoleState requested, RoleState response) {
            LOG.debug("receivedRoleReply({},{},{})", dpid, requested, response);
            MastershipRole request = roleOf(requested);
            MastershipRole reply = roleOf(response);
            providerService.receivedRoleReply(deviceId(uri(dpid)), request, reply);
        }

        /**
         * Translates a RoleState to the corresponding MastershipRole.
         *
         * @param response role state
         * @return a MastershipRole
         */
        private MastershipRole roleOf(RoleState response) {
            switch (response) {
                case MASTER:
                    return MastershipRole.MASTER;
                case EQUAL:
                    return MastershipRole.STANDBY;
                case SLAVE:
                    return MastershipRole.NONE;
                default:
                    LOG.warn("unknown role {}", response);
                    return null;
            }
        }

        /**
         * Builds a list of port descriptions for a given list of ports.
         *
         * @return list of portdescriptions
         */
        private List<PortDescription> buildPortDescriptions(OpenFlowSwitch sw) {
            List<OFPortDesc> ofPorts = sw.getPorts();
            final List<PortDescription> portDescs = new ArrayList<>(ofPorts.size());
            if (!((Device.Type.ROADM.equals(sw.deviceType())) ||
                    (Device.Type.OTN.equals(sw.deviceType())) ||
                    (Device.Type.OPTICAL_AMPLIFIER.equals(sw.deviceType())))) {
                // build regular (=non-optical) Device ports
                ofPorts.forEach(port -> portDescs.add(buildPortDescription(port)));
            }

            // TODO handle Optical Device, but plain OF devices(1.4 and later)

            OpenFlowOpticalSwitch opsw;
            switch (sw.deviceType()) {
                case ROADM:
                case OTN:
                case OPTICAL_AMPLIFIER:
                    opsw = (OpenFlowOpticalSwitch) sw;
                    List<OFPortDesc> ports = opsw.getPorts();
                    LOG.debug("SW ID {} , ETH- ODU CLT Ports {}", opsw.getId(), ports);
                    // ODU client ports are reported as ETH
                    ports.forEach(port -> portDescs.add(buildOduCltPortDescription(port)));

                    opsw.getPortTypes().forEach(type -> {
                    List<? extends OFObject> portsOf = opsw.getPortsOf(type);
                    LOG.debug("Ports Of{}", portsOf);
                    portsOf.forEach(
                        op -> {
                            portDescs.add(buildPortDescription(type, op, opsw));
                        }
                     );
                    });
                    break;
                case FIBER_SWITCH:
                    opsw = (OpenFlowOpticalSwitch) sw;
                    opsw.getPortTypes().forEach(type -> {
                        opsw.getPortsOf(type).forEach(op -> {
                            if (op instanceof OFPortDesc) {
                                // ports using standard optical extension
                                // TODO OFMessage -> PortDescription should
                                // probably be a Behaviour
                                portDescs.add(oms(buildPortDescription((OFPortDesc) op)));
                            } else if (op instanceof OFCalientPortDescStatsEntry) {
                                // calient extension
                                portDescs.add(buildPortDescription((OFCalientPortDescStatsEntry) op));
                            } else {
                                LOG.warn("Unexpected FIBER_SWITCH port {} on {}",
                                         op, sw.getStringId());
                            }
                        });
                    });
                    break;
                default:
                    break;
            }

            return portDescs;
        }

        /**
         * Ensures returned PortDescription is an OMS port.
         *
         * @param descr input PortDescription
         * @return OMS PortDescription
         */
        private PortDescription oms(PortDescription descr) {
            // Hack until OFMessage -> PortDescription transformation
            // becomes a Behaviour
            if (descr.type() == Type.OMS) {
                return descr;
            }

            Builder builder = DefaultAnnotations.builder();
            builder.putAll(descr.annotations());

            // set reasonable default when mandatory key is missing
            if (Strings.isNullOrEmpty(descr.annotations().value(AK_MIN_FREQ_HZ))) {
                builder.set(AK_MIN_FREQ_HZ, String.valueOf(Spectrum.O_BAND_MIN.asHz()));
            }

            if (Strings.isNullOrEmpty(descr.annotations().value(AK_MAX_FREQ_HZ))) {
                builder.set(AK_MAX_FREQ_HZ, String.valueOf(Spectrum.O_BAND_MAX.asHz()));
            }

            if (Strings.isNullOrEmpty(descr.annotations().value(AK_GRID_HZ))) {
                builder.set(AK_GRID_HZ, String.valueOf(Frequency.ofGHz(50).asHz()));
            }

            return DefaultPortDescription.builder(descr)
                    .type(Type.OMS)
                    .annotations(builder.build())
                    .build();
        }

        private PortDescription buildOduCltPortDescription(OFPortDesc port) {
            PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
            boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN) &&
                              !port.getConfig().contains(OFPortConfig.PORT_DOWN);
            Long portSpeedInMbps = portSpeed(port);
            CltSignalType sigType = null;

            switch (portSpeedInMbps.toString()) {
                case "1000":
                    sigType = CltSignalType.CLT_1GBE;
                    break;
                case "10000":
                    sigType = CltSignalType.CLT_10GBE;
                    break;
                case "40000":
                    sigType = CltSignalType.CLT_40GBE;
                    break;
                case "100000":
                    sigType = CltSignalType.CLT_100GBE;
                    break;
                default:
                    throw new IllegalArgumentException("Un recognize OduClt speed: " + portSpeedInMbps.toString());
            }

            SparseAnnotations annotations = buildOduCltAnnotation(port);
            return oduCltPortDescription(portNo, enabled, sigType, annotations);
        }

        private SparseAnnotations buildOduCltAnnotation(OFPortDesc port) {
            SparseAnnotations annotations = null;
            String portName = Strings.emptyToNull(port.getName());
            if (portName != null) {
                 annotations = DefaultAnnotations.builder()
                        .set(AnnotationKeys.PORT_NAME, portName)
                        .set(AnnotationKeys.STATIC_PORT, Boolean.TRUE.toString()).build();
            }
            return annotations;
        }

        private PortDescription buildPortDescription(PortDescPropertyType ptype, OFObject port,
                OpenFlowOpticalSwitch opsw) {
            if (port instanceof OFPortOptical) {
                return buildPortDescription(ptype, (OFPortOptical) port, opsw);
            }
            return buildPortDescription(ptype, (OFExpPort) port);
        }

        private boolean matchingOtuPortSignalTypes(OFPortOpticalTransportSignalType sigType,
                OduSignalType oduSignalType) {
            switch (sigType) {
            case OTU2:
                if (oduSignalType == OduSignalType.ODU2) {
                    return true;
                }
                break;
            case OTU4:
                if (oduSignalType == OduSignalType.ODU4) {
                    return true;
                }
                break;
            default:
                break;
            }
            return false;
        }
        /**
         * Build a portDescription from a given a port description describing some
         * Optical port.
         *
         * @param ptype description property type.
         * @param port the port to build from.
         * @return portDescription for the port.
         */
        private PortDescription buildPortDescription(PortDescPropertyType ptype, OFExpPort port) {
            PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
            boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN)
                    && !port.getConfig().contains(OFPortConfig.PORT_DOWN);
            boolean adminDown = port.getConfig().contains(OFPortConfig.PORT_DOWN);
            SparseAnnotations annotations = makePortAnnotation(port.getName(),
                                                               port.getHwAddr().toString(),
                                                               adminDown).build();

            OFExpPortDescPropOpticalTransport firstProp = port.getProperties().get(0);
            OFPortOpticalTransportSignalType sigType = firstProp.getPortSignalType();

            PortDescription portDes = null;
            switch (sigType) {
            case OMSN:
                portDes = omsPortDescription(portNo, enabled,
                        FREQ191_7, FREQ191_7.add(FREQ4_4), FREQ50, annotations);
                break;
            case OCH:
                OFExpPortOpticalTransportLayerEntry entry = firstProp.getFeatures().get(0).getValue().get(0);
                OFPortOpticalTransportLayerClass layerClass =  entry.getLayerClass();
                if (!OFPortOpticalTransportLayerClass.ODU.equals(layerClass)) {
                    LOG.error("Unsupported layer Class {} ", layerClass);
                    return null;
                }

                // convert to ONOS OduSignalType
                OduSignalType oduSignalType = OpenFlowDeviceValueMapper.
                        lookupOduSignalType((byte) entry.getSignalType());
                //OchSignal is needed for OchPortDescription constructor,
                //yet not relevant for tunable OCH port, creating with default parameters
                OchSignal signalId = new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, 1, 1);

                portDes = ochPortDescription(portNo, enabled,
                                             oduSignalType, true,
                                             signalId, annotations);

                break;
            case OTU2:
            case OTU4:
                entry = firstProp.getFeatures().get(0).getValue().get(0);
                layerClass =  entry.getLayerClass();
                if (!OFPortOpticalTransportLayerClass.ODU.equals(layerClass)) {
                    LOG.error("Unsupported layer Class {} ", layerClass);
                    return null;
                }

                // convert to ONOS OduSignalType
                OduSignalType oduSignalTypeOtuPort = OpenFlowDeviceValueMapper.
                        lookupOduSignalType((byte) entry.getSignalType());
                if (!matchingOtuPortSignalTypes(sigType, oduSignalTypeOtuPort)) {
                    LOG.error("Wrong oduSignalType {} for OTU Port sigType {} ", oduSignalTypeOtuPort, sigType);
                    return null;
                }
                OtuSignalType otuSignalType =
                        ((sigType == OFPortOpticalTransportSignalType.OTU2) ? OtuSignalType.OTU2 :
                            OtuSignalType.OTU4);
                portDes = otuPortDescription(portNo, enabled, otuSignalType, annotations);
                break;
            default:
                break;
            }

            return portDes;
        }

        /**
         * Creates an annotation builder for the port name if one is available.
         *
         * @param portName the port name
         * @param portMac the port mac
         * @param adminDown the port admin state
         * @return annotation builder containing port admin state, port name
         *          and/or port MAC if any of the two is found
         */
        private DefaultAnnotations.Builder makePortAnnotation(String portName, String portMac, boolean adminDown) {
            DefaultAnnotations.Builder builder = DefaultAnnotations.builder();
            String pName = Strings.emptyToNull(portName);
            String pMac = Strings.emptyToNull(portMac);
            if (pName != null) {
                builder.set(AnnotationKeys.PORT_NAME, pName);
            }
            if (pMac != null) {
                builder.set(AnnotationKeys.PORT_MAC, pMac);
            }
            String adminState = adminDown ? "disabled" : "enabled";
            builder.set(AnnotationKeys.ADMIN_STATE, adminState);
            return builder;
        }

        private PortDescription buildPortDescription14(OFPortDesc port) {
            PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
            boolean enabled =
                    !port.getState().contains(OFPortState.LINK_DOWN) &&
                    !port.getConfig().contains(OFPortConfig.PORT_DOWN);
            boolean adminDown = port.getConfig().contains(OFPortConfig.PORT_DOWN);
            Builder annotations = makePortAnnotation(port.getName(),
                                                               port.getHwAddr().toString(),
                                                               adminDown);

            Optional<OFPortDescPropEthernet> ether = port.getProperties().stream()
                .filter(OFPortDescPropEthernet.class::isInstance)
                .map(OFPortDescPropEthernet.class::cast)
                .findAny();
            if (ether.isPresent()) {
                // ethernet port
                // TODO parse other part of OFPortDescPropEthernet if necessary
                return DefaultPortDescription.builder()
                        .withPortNumber(portNo)
                        .isEnabled(enabled)
                        .type(COPPER)
                        .portSpeed(portSpeed(port))
                        .annotations(annotations.build())
                        .build();
            }

            Optional<OFPortDescPropOptical> optical = port.getProperties().stream()
                    .filter(OFPortDescPropOptical.class::isInstance)
                    .map(OFPortDescPropOptical.class::cast)
                    .findAny();
            if (optical.isPresent()) {
                // optical port

                // FIXME is there a OF version neutral way to access
                // OFOpticalPortFeaturesSerializerVer14

                long supported = optical.get().getSupported();
                long rxMin = optical.get().getRxMinFreqLmda();
                long rxMax = optical.get().getRxMaxFreqLmda();
                long rxGrid = optical.get().getRxGridFreqLmda();
                long txMin = optical.get().getTxMinFreqLmda();
                long txMax = optical.get().getTxMaxFreqLmda();
                long txGrid = optical.get().getTxGridFreqLmda();

                int txTune = OFOpticalPortFeaturesSerializerVer14.TX_TUNE_VAL;
                int rxTune = OFOpticalPortFeaturesSerializerVer14.RX_TUNE_VAL;
                annotations.set(AK_TX_TUNE_FEATURE,
                        ((supported & txTune) != 0) ? "enabled" : "disabled");
                annotations.set(AK_RX_TUNE_FEATURE,
                        ((supported & rxTune) != 0) ? "enabled" : "disabled");

                // wire value for OFOpticalPortFeatures.USE_FREQ
                boolean useFreq = (supported & OFOpticalPortFeaturesSerializerVer14.USE_FREQ_VAL) != 0;
                annotations.set(AK_USE_FREQ_FEATURE, useFreq ? "enabled" : "disabled");

                annotations.set(propFreq ? AK_RX_MIN_FREQ_HZ : AK_RX_MIN_LMDA_NM,
                                freqLmdaToAnnotation(rxMin, useFreq));
                annotations.set(propFreq ? AK_RX_MAX_FREQ_HZ : AK_RX_MAX_LMDA_NM,
                                freqLmdaToAnnotation(rxMax, useFreq));
                annotations.set(propFreq ? AK_RX_GRID_HZ : AK_RX_GRID_LMDA_NM,
                                freqLmdaToAnnotation(rxGrid, useFreq));

                annotations.set(propFreq ? AK_TX_MIN_FREQ_HZ : AK_TX_MIN_LMDA_NM,
                                freqLmdaToAnnotation(txMin, useFreq));
                annotations.set(propFreq ? AK_TX_MAX_FREQ_HZ : AK_TX_MAX_LMDA_NM,
                                freqLmdaToAnnotation(txMax, useFreq));
                annotations.set(propFreq ? AK_TX_GRID_HZ : AK_TX_GRID_LMDA_NM,
                                freqLmdaToAnnotation(txGrid, useFreq));

                // FIXME pretty confident this is not going to happen
                // unless Device models Tx/Rx ports as separate port
                if (rxMin == txMin) {
                    annotations.set(propFreq ? AK_MIN_FREQ_HZ : AK_MIN_LMDA_NM,
                                    freqLmdaToAnnotation(rxMin, useFreq));
                }
                if (rxMax == txMax) {
                    annotations.set(propFreq ? AK_MAX_FREQ_HZ : AK_MAX_LMDA_NM,
                                    freqLmdaToAnnotation(rxMax, useFreq));
                }
                if (rxGrid == txGrid) {
                    annotations.set(propFreq ? AK_GRID_HZ : AK_GRID_LMDA_NM,
                                    freqLmdaToAnnotation(rxGrid, useFreq));
                }

                int txPwr = OFOpticalPortFeaturesSerializerVer14.TX_PWR_VAL;
                long txPwrMin = optical.get().getTxPwrMin();
                long txPwrMax = optical.get().getTxPwrMax();
                annotations.set(AK_TX_PWR_FEATURE, ((supported & txPwr) != 0) ? "enabled" : "disabled");
                annotations.set(AK_TX_PWR_MIN, Long.toString(txPwrMin));
                annotations.set(AK_TX_PWR_MAX, Long.toString(txPwrMax));

                // TODO How to determine appropriate port type?

                return DefaultPortDescription.builder()
                        .withPortNumber(portNo)
                        .isEnabled(enabled)
                        .type(FIBER)
                        .portSpeed(portSpeed(port))
                        .annotations(annotations.build())
                        .build();
            }

            // fall back default
            return DefaultPortDescription.builder()
                    .withPortNumber(portNo)
                    .isEnabled(enabled)
                    .type(COPPER)
                    .portSpeed(portSpeed(port))
                    .annotations(annotations.build())
                    .build();

        }

        /**
         * Build a portDescription from a given Ethernet port description.
         *
         * @param port the port to build from.
         * @return portDescription for the port.
         */
        private PortDescription buildPortDescription(OFPortDesc port) {
            if (port.getVersion().wireVersion >= OFVersion.OF_14.getWireVersion()) {
                return buildPortDescription14(port);
            }
            PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());
            boolean enabled =
                    !port.getState().contains(OFPortState.LINK_DOWN) &&
                            !port.getConfig().contains(OFPortConfig.PORT_DOWN);
            Port.Type type = port.getCurr().contains(OFPortFeatures.PF_FIBER) ? FIBER : COPPER;
            boolean adminDown = port.getConfig().contains(OFPortConfig.PORT_DOWN);
            SparseAnnotations annotations = makePortAnnotation(port.getName(),
                                                               port.getHwAddr().toString(),
                                                               adminDown).build();
            return DefaultPortDescription.builder()
                    .withPortNumber(portNo)
                    .isEnabled(enabled)
                    .type(type)
                    .portSpeed(portSpeed(port))
                    .annotations(annotations)
                    .build();
        }

        /**
         * Build a portDescription from a given a port description describing some
         * Optical port.
         *
         * @param port description property type.
         * @param port the port to build from.
         * @return portDescription for the port.
         */
        private PortDescription buildPortDescription(PortDescPropertyType ptype, OFPortOptical port,
                OpenFlowOpticalSwitch opsw) {
            checkArgument(!port.getDesc().isEmpty());

            // Minimally functional fixture. This needs to be fixed as we add better support.
            PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());

            boolean enabled = !port.getState().contains(OFPortState.LINK_DOWN)
                    && !port.getConfig().contains(OFPortConfig.PORT_DOWN);
            boolean adminDown = port.getConfig().contains(OFPortConfig.PORT_DOWN);
            SparseAnnotations annotations = makePortAnnotation(port.getName(),
                                                               port.getHwAddr().toString(),
                                                               adminDown).build();

            if (port.getVersion() == OFVersion.OF_13
                    && ptype == PortDescPropertyType.OPTICAL_TRANSPORT) {
                // At this point, not much is carried in the optical port message.
                LOG.debug("Optical transport port message {}", port.toString());
            } else {
                // removable once 1.4+ support complete.
                LOG.debug("Unsupported optical port properties");
            }

            OFPortDescPropOpticalTransport desc = port.getDesc().get(0);
            switch (desc.getPortSignalType()) {
                // FIXME: use constants once loxi has full optical extensions
                case 2:     // OMS port
                    // Assume complete optical spectrum and 50 GHz grid
                    Set<OchSignal> signals = null;
                    if (opsw instanceof HandlerBehaviour) {
                        DriverHandler driverHandler = ((HandlerBehaviour) opsw).handler();
                        if (driverHandler != null && driverHandler.hasBehaviour(LambdaQuery.class)) {
                            try {
                                signals = driverHandler.behaviour(LambdaQuery.class).queryLambdas(portNo);
                            } catch (NullPointerException e) {
                                signals = null;
                            }
                        }
                    }
                    Frequency minFreq;
                    Frequency maxFreq;
                    Frequency channelSpacing;
                    if (signals == null || signals.isEmpty()) {
                        minFreq = Spectrum.U_BAND_MIN;
                        maxFreq = Spectrum.O_BAND_MAX;
                        channelSpacing = Frequency.ofGHz(50);
                    } else {
                        Comparator<OchSignal> compare =
                                (OchSignal a, OchSignal b) -> a.spacingMultiplier() - b.spacingMultiplier();
                        OchSignal minOch = Collections.min(signals, compare);
                        OchSignal maxOch = Collections.max(signals, compare);
                        minFreq = minOch.centralFrequency();
                        maxFreq = maxOch.centralFrequency();
                        channelSpacing = minOch.channelSpacing().frequency();
                    }
                    return omsPortDescription(portNo, enabled, minFreq,
                            maxFreq, channelSpacing, annotations);
                case 5:     // OCH port
                    OchSignal signal = new OchSignal(GridType.DWDM, ChannelSpacing.CHL_50GHZ, 0, 4);
                    return ochPortDescription(portNo, enabled, OduSignalType.ODU4,
                            true, signal, annotations);
                default:
                    break;
            }

            return DefaultPortDescription.builder()
                    .withPortNumber(portNo)
                    .isEnabled(enabled)
                    .type(FIBER)
                    .portSpeed(0)
                    .annotations(annotations)
                    .build();
        }

        /**
         * Build a portDescription from a given port description describing a fiber switch optical port.
         *
         * @param port description property type.
         * @param port the port to build from.
         * @return portDescription for the port.
         */
        private PortDescription buildPortDescription(OFCalientPortDescStatsEntry port) {
            PortNumber portNo = PortNumber.portNumber(port.getPortNo().getPortNumber());

            // Use the alias name if it's available
            String name = port.getName();
            List<OFCalientPortDescProp> props = port.getProperties();
            if (props != null && !props.isEmpty()) {
                OFCalientPortDescPropOptical propOptical = (OFCalientPortDescPropOptical) props.get(0);
                if (propOptical != null) {
                    name = propOptical.getInAlias();
                }
            }

            // FIXME when Calient OF agent reports port status
            boolean enabled = true;
            boolean adminDown = false;
            SparseAnnotations annotations = makePortAnnotation(name, port.getHwAddr().toString(), adminDown).build();

            // S160 data sheet
            // Wavelength range: 1260 - 1630 nm, grid is irrelevant for this type of switch
            return omsPortDescription(portNo, enabled,
                    Spectrum.O_BAND_MIN, Spectrum.O_BAND_MAX, Frequency.ofGHz(50), annotations);
        }

        private PortDescription buildPortDescription(OFPortStatus status) {
            OFPortDesc port = status.getDesc();
            if (status.getReason() != OFPortReason.DELETE) {
                return buildPortDescription(port);
            } else {
                PortDescription desc = buildPortDescription(port);
                if (desc.isEnabled()) {
                    return DefaultPortDescription.builder(desc)
                            .isEnabled(false)
                            .build();
                }
                return desc;
            }
        }

        /**
         * Returns port speed in Mbps.
         *
         * @param port description to parse
         * @return port speed in Mbps
         */
        private long portSpeed(OFPortDesc port) {
            if (port.getVersion().getWireVersion() >= OFVersion.OF_14.getWireVersion()) {
                // OFPortDescPropEthernet
                return port.getProperties().stream()
                        .filter(OFPortDescPropEthernet.class::isInstance)
                        .map(OFPortDescPropEthernet.class::cast)
                        .mapToLong(OFPortDescPropEthernet::getCurrSpeed)
                        .map(kbps -> kbps / KBPS)
                        .findAny()
                        .orElse(PortSpeed.SPEED_NONE.getSpeedBps() / MBPS);
            }
            if (port.getVersion() == OFVersion.OF_13) {
                // Note: getCurrSpeed() returns a value in kbps (this also applies to OF_11 and OF_12)
                return port.getCurrSpeed() / KBPS;
            }
            // < OF1.3
            PortSpeed portSpeed = PortSpeed.SPEED_NONE;
            for (OFPortFeatures feat : port.getCurr()) {
                portSpeed = PortSpeed.max(portSpeed, feat.getPortSpeed());
            }
            return portSpeed.getSpeedBps() / MBPS;
        }

        @Override
        public void handleMessage(Dpid dpid, OFMessage msg) {
            if (isDisabled) {
                return;
            }

            try {
                switch (msg.getType()) {
                    case STATS_REPLY:
                        if (((OFStatsReply) msg).getStatsType() == OFStatsType.PORT) {
                            OFPortStatsReply portStatsReply = (OFPortStatsReply) msg;
                            List<OFPortStatsEntry> portStatsReplyList = portStatsReplies.get(dpid);
                            if (portStatsReplyList == null) {
                                portStatsReplyList = Lists.newCopyOnWriteArrayList();
                            }
                            portStatsReplyList.addAll(portStatsReply.getEntries());
                            portStatsReplies.put(dpid, portStatsReplyList);
                            if (!portStatsReply.getFlags().contains(OFStatsReplyFlags.REPLY_MORE)) {
                                List<OFPortStatsEntry> statsEntries = portStatsReplies.get(dpid);
                                if (statsEntries != null) {
                                    pushPortMetrics(dpid, statsEntries);
                                    statsEntries.clear();
                                }
                            }
                        } else if (((OFStatsReply) msg).getStatsType() == OFStatsType.EXPERIMENTER) {
                            OpenFlowSwitch sw = controller.getSwitch(dpid);
                            if (sw == null) {
                                LOG.error("Switch {} is not found", dpid);
                                break;
                            }
                            if (sw instanceof OpenFlowOpticalSwitch) {
                                // Optical switch uses experimenter stats message to update power
                                List<PortDescription> portDescs =
                                        ((OpenFlowOpticalSwitch) sw).processExpPortStats(msg);
                                if (!portDescs.isEmpty()) {
                                    providerService.updatePorts(DeviceId.deviceId(Dpid.uri(dpid)), portDescs);
                                }
                            }
                        }
                        break;
                    case ERROR:
                        if (((OFErrorMsg) msg).getErrType() == OFErrorType.PORT_MOD_FAILED) {
                            LOG.error("port mod failed");
                        }
                        break;
                    default:
                        break;
                }
            } catch (IllegalStateException e) {
                // system is shutting down and the providerService is no longer
                // valid. Messages cannot be processed.
            }
        }

        private void disable() {
            isDisabled = true;
        }
    }

}
