/*
 * Copyright 2017-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.drivers.server;

import org.onosproject.drivers.server.behavior.CpuStatisticsDiscovery;
import org.onosproject.drivers.server.behavior.MonitoringStatisticsDiscovery;
import org.onosproject.drivers.server.devices.CpuDevice;
import org.onosproject.drivers.server.devices.CpuVendor;
import org.onosproject.drivers.server.devices.nic.NicDevice;
import org.onosproject.drivers.server.devices.nic.NicRxFilter;
import org.onosproject.drivers.server.devices.nic.NicRxFilter.RxFilter;
import org.onosproject.drivers.server.devices.ServerDeviceDescription;
import org.onosproject.drivers.server.devices.RestServerSBDevice;
import org.onosproject.drivers.server.stats.CpuStatistics;
import org.onosproject.drivers.server.stats.MonitoringStatistics;
import org.onosproject.drivers.server.stats.TimingStatistics;

import org.onosproject.drivers.server.impl.devices.DefaultCpuDevice;
import org.onosproject.drivers.server.impl.devices.DefaultNicDevice;
import org.onosproject.drivers.server.impl.devices.DefaultRestServerSBDevice;
import org.onosproject.drivers.server.impl.devices.DefaultServerDeviceDescription;
import org.onosproject.drivers.server.impl.stats.DefaultCpuStatistics;
import org.onosproject.drivers.server.impl.stats.DefaultMonitoringStatistics;
import org.onosproject.drivers.server.impl.stats.DefaultTimingStatistics;

import org.onlab.packet.ChassisId;
import org.onosproject.net.AnnotationKeys;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.DefaultAnnotations;
import org.onosproject.net.behaviour.DevicesDiscovery;
import org.onosproject.net.device.DeviceDescription;
import org.onosproject.net.device.DeviceDescriptionDiscovery;
import org.onosproject.net.device.DefaultPortStatistics;
import org.onosproject.net.device.DefaultPortDescription;
import org.onosproject.net.device.PortDescription;
import org.onosproject.net.device.PortStatistics;
import org.onosproject.net.device.PortStatisticsDiscovery;
import org.onosproject.net.Port;
import org.onosproject.net.PortNumber;
import org.onosproject.protocol.rest.RestSBDevice;
import org.onosproject.protocol.rest.RestSBDevice.AuthenticationScheme;

import org.slf4j.Logger;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;

import com.google.common.collect.Lists;
import com.google.common.collect.ImmutableList;

import javax.ws.rs.ProcessingException;
import java.io.InputStream;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import static com.google.common.base.Preconditions.checkNotNull;
import static org.slf4j.LoggerFactory.getLogger;

/**
 * Discovers the device details of
 * REST-based commodity server devices.
 */
public class ServerDevicesDiscovery extends BasicServerDriver
        implements  DevicesDiscovery, DeviceDescriptionDiscovery,
                    PortStatisticsDiscovery, CpuStatisticsDiscovery,
                    MonitoringStatisticsDiscovery {

    private final Logger log = getLogger(getClass());

    /**
     * Resource endpoints of the server agent (REST server-side).
     */
    private static final String RESOURCE_DISCOVERY_URL   = BASE_URL + "/resources";
    private static final String GLOBAL_STATS_URL         = BASE_URL + "/stats";
    private static final String SERVICE_CHAINS_STATS_URL = BASE_URL + "/chains_stats";  // + /ID

    /**
     * Parameters to be exchanged with the server's agent.
     */
    private static final String PARAM_MANUFACTURER     = "manufacturer";
    private static final String PARAM_HW_VENDOR        = "hwVersion";
    private static final String PARAM_SW_VENDOR        = "swVersion";
    private static final String PARAM_SERIAL           = "serial";
    private static final String PARAM_TIMING_STATS     = "timing_stats";
    private static final String PARAM_TIMING_AUTOSCALE = "autoscale_timing_stats";

    private static final String NIC_PARAM_ID               = "id";
    private static final String NIC_PARAM_PORT_TYPE        = "portType";
    private static final String NIC_PARAM_PORT_TYPE_FIBER  = "fiber";
    private static final String NIC_PARAM_PORT_TYPE_COPPER = "copper";
    private static final String NIC_PARAM_SPEED            = "speed";
    private static final String NIC_PARAM_STATUS           = "status";
    private static final String NIC_PARAM_HW_ADDR          = "hwAddr";

    /**
     * NIC statistics.
     */
    private static final String NIC_STATS_TX_COUNT  = "txCount";
    private static final String NIC_STATS_TX_BYTES  = "txBytes";
    private static final String NIC_STATS_TX_DROPS  = "txDropped";
    private static final String NIC_STATS_TX_ERRORS = "txErrors";
    private static final String NIC_STATS_RX_COUNT  = "rxCount";
    private static final String NIC_STATS_RX_BYTES  = "rxBytes";
    private static final String NIC_STATS_RX_DROPS  = "rxDropped";
    private static final String NIC_STATS_RX_ERRORS = "rxErrors";

    /**
     * CPU statistics.
     */
    private static final String CPU_PARAM_ID        = "id";
    private static final String CPU_PARAM_VENDOR    = "vendor";
    private static final String CPU_PARAM_FREQUENCY = "frequency";
    private static final String CPU_PARAM_LOAD      = "load";
    private static final String CPU_PARAM_STATUS    = "busy";
    private static final String CPU_STATS_BUSY_CPUS = "busyCpus";
    private static final String CPU_STATS_FREE_CPUS = "freeCpus";

    /**
     * Timing statistics.
     */
    private static final String TIMING_PARAM_PARSE     = "parse";
    private static final String TIMING_PARAM_LAUNCH    = "launch";
    private static final String TIMING_PARAM_AUTOSCALE = "autoscale";

    /**
     * Auxiliary constants.
     */
    private static final short  DISCOVERY_RETRIES  = 3;
    private static final String CPU_VENDOR_NULL    = "Unsupported CPU vendor" +
        " Choose one in: " + BasicServerDriver.enumTypesToString(CpuVendor.class);
    private static final String NIC_RX_FILTER_NULL = "Unsupported NIC Rx filter" +
        " Choose one in: " + BasicServerDriver.enumTypesToString(RxFilter.class);

    /**
     * Port types that usually appear in commodity servers.
     */
    public static final Map<String, Port.Type> PORT_TYPE_MAP =
        Collections.unmodifiableMap(
            new HashMap<String, Port.Type>() {
                {
                    put(NIC_PARAM_PORT_TYPE_FIBER,  Port.Type.FIBER);
                    put(NIC_PARAM_PORT_TYPE_COPPER, Port.Type.COPPER);
                }
            }
        );

    /**
     * Constructs server device discovery.
     */
    public ServerDevicesDiscovery() {
        super();
        log.debug("Started");
    }

    @Override
    public Set<DeviceId> deviceIds() {
        // Set of devices to return
        Set<DeviceId> devices = new HashSet<DeviceId>();

        DeviceId deviceId = getHandler().data().deviceId();
        checkNotNull(deviceId, DEVICE_ID_NULL);
        devices.add(deviceId);

        return devices;
    }

    @Override
    public DeviceDescription deviceDetails(DeviceId deviceId) {
        return getDeviceDetails(deviceId);
    }

    @Override
    public DeviceDescription discoverDeviceDetails() {
        return getDeviceDetails(null);
    }

    /**
     * Query a server to retrieve its features.
     *
     * @param deviceId the device ID to be queried
     * @return a DeviceDescription with the device's features
     */
    private DeviceDescription getDeviceDetails(DeviceId deviceId) {
        // Create a description for this server device
        ServerDeviceDescription desc = null;

        // Retrieve the device ID, if null given
        if (deviceId == null) {
            deviceId = getHandler().data().deviceId();
            checkNotNull(deviceId, DEVICE_ID_NULL);
        }

        // Get the device
        RestSBDevice device = getController().getDevice(deviceId);
        checkNotNull(device, DEVICE_NULL);

        // Hit the path that provides the server's resources
        InputStream response = null;
        try {
            response = getController().get(
                deviceId,
                RESOURCE_DISCOVERY_URL,
                JSON
            );
        } catch (ProcessingException pEx) {
            log.error("Failed to discover the device details of: {}", deviceId);
            return desc;
        }

        // Load the JSON into objects
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> jsonMap = null;
        JsonNode jsonNode = null;
        ObjectNode objNode = null;
        try {
            jsonMap  = mapper.readValue(response, Map.class);
            jsonNode = mapper.convertValue(jsonMap, JsonNode.class);
            objNode = (ObjectNode) jsonNode;
        } catch (IOException ioEx) {
            log.error("Failed to discover the device details of: {}", deviceId);
            return desc;
        }

        if (jsonMap == null) {
            log.error("Failed to discover the device details of: {}", deviceId);
            return desc;
        }

        // Get all the attributes
        String id     = get(jsonNode, BasicServerDriver.PARAM_ID);
        String vendor = get(jsonNode, PARAM_MANUFACTURER);
        String hw     = get(jsonNode, PARAM_HW_VENDOR);
        String sw     = get(jsonNode, PARAM_SW_VENDOR);
        String serial = get(jsonNode, PARAM_SERIAL);

        // CPUs are composite attributes
        Set<CpuDevice> cpuSet = new HashSet<CpuDevice>();
        JsonNode cpuNode = objNode.path(BasicServerDriver.PARAM_CPUS);

        // Construct CPU objects
        for (JsonNode cn : cpuNode) {
            ObjectNode cpuObjNode = (ObjectNode) cn;

            // All the CPU attributes
            int           cpuId = cpuObjNode.path(CPU_PARAM_ID).asInt();
            String cpuVendorStr = get(cn, CPU_PARAM_VENDOR);
            long   cpuFrequency = cpuObjNode.path(CPU_PARAM_FREQUENCY).asLong();

            // Verify that this is a valid vendor
            CpuVendor cpuVendor = CpuVendor.getByName(cpuVendorStr);
            checkNotNull(cpuVendor, CPU_VENDOR_NULL);

            // Construct a CPU device
            CpuDevice cpu = new DefaultCpuDevice(cpuId, cpuVendor, cpuFrequency);

            // Add it to the set
            cpuSet.add(cpu);
        }

        // NICs are composite attributes too
        Set<NicDevice> nicSet = new HashSet<NicDevice>();
        JsonNode nicNode = objNode.path(PARAM_NICS);

        // Construct NIC objects
        for (JsonNode nn : nicNode) {
            ObjectNode nicObjNode = (ObjectNode) nn;

            // All the NIC attributes
            String nicId       = get(nn, NIC_PARAM_ID);
            int port           = Integer.parseInt(nicId.replaceAll("\\D+", ""));
            long speed         = nicObjNode.path(NIC_PARAM_SPEED).asLong();
            String portTypeStr = get(nn, NIC_PARAM_PORT_TYPE);
            Port.Type portType = PORT_TYPE_MAP.get(portTypeStr);
            if (portType == null) {
                throw new IllegalArgumentException(
                    portTypeStr + " is not a valid port type for NIC " + nicId
                );
            }
            boolean status     = nicObjNode.path(NIC_PARAM_STATUS).asInt() > 0;
            String hwAddr      = get(nn, NIC_PARAM_HW_ADDR);
            JsonNode tagNode   = nicObjNode.path(BasicServerDriver.NIC_PARAM_RX_FILTER);
            if (tagNode == null) {
                throw new IllegalArgumentException(
                    "The Rx filters of NIC " + nicId + " are not reported"
                );
            }

            // Convert the JSON list into an array of strings
            List<String> rxFilters = null;
            try {
                rxFilters = mapper.readValue(
                    tagNode.traverse(),
                    new TypeReference<ArrayList<String>>() { }
                );
            } catch (IOException ioEx) {
                continue;
            }

            // Parse the array of strings and create an RxFilter object
            NicRxFilter rxFilterMechanism = new NicRxFilter();
            for (String s : rxFilters) {
                // Verify that this is a valid Rx filter
                RxFilter rf = RxFilter.getByName(s);
                checkNotNull(rf, NIC_RX_FILTER_NULL);

                rxFilterMechanism.addRxFilter(rf);
            }

            // Construct a NIC device for this server
            NicDevice nic = new DefaultNicDevice(
                nicId, port, portType, speed, status, hwAddr, rxFilterMechanism
            );

            // Add it to the set
            nicSet.add(nic);
        }

        // Construct a complete server device object.
        // Lists of NICs and CPUs extend the information
        // already in RestSBDevice (parent class).
        RestServerSBDevice dev = new DefaultRestServerSBDevice(
            device.ip(), device.port(), device.username(),
            device.password(), device.protocol(), device.url(),
            device.isActive(), device.testUrl().toString(),
            vendor, hw, sw, AuthenticationScheme.BASIC, "",
            cpuSet, nicSet
        );
        checkNotNull(dev, DEVICE_NULL);

        // Updates the controller with the complete device information
        getController().removeDevice(deviceId);
        getController().addDevice((RestSBDevice) dev);

        /**
         * TODO: Create a new Device type
         * Device.Type.COMMODITY_SERVER
         * and add a new icon in the GUI.
         */
        try {
            desc = new DefaultServerDeviceDescription(
                new URI(id), Device.Type.OTHER, vendor,
                hw, sw, serial, new ChassisId(),
                cpuSet, nicSet, DefaultAnnotations.EMPTY
            );
        } catch (URISyntaxException uEx) {
            log.error(
                "Failed to create a server device description for: {}", deviceId
            );
            return null;
        }

        log.info("Device's {} details sent to the controller", deviceId);

        return desc;
    }

    @Override
    public List<PortDescription> discoverPortDetails() {
        // List of port descriptions to return
        List<PortDescription> portDescriptions = Lists.newArrayList();

        // Retrieve the device ID
        DeviceId deviceId = getHandler().data().deviceId();
        checkNotNull(deviceId, DEVICE_ID_NULL);
        // .. and object
        RestServerSBDevice device = null;

        // In case this method is called before discoverDeviceDetails,
        // there is missing information to be gathered.
        short i = 0;
        while ((device == null) && (i < DISCOVERY_RETRIES)) {
            i++;

            try {
                device = (RestServerSBDevice) getController().getDevice(deviceId);
            } catch (ClassCastException ccEx) {
                try {
                    Thread.sleep(1);
                } catch (InterruptedException intEx) {
                    // Just retry
                    continue;
                }
            }

            // No device
            if (device == null) {
                // This method will add the device to the RestSBController
                this.getDeviceDetails(deviceId);
            }
        }

        if ((device == null) || (device.nics() == null)) {
            log.error("No ports available on {}", deviceId);
            return ImmutableList.copyOf(portDescriptions);
        }

        // Sorted list of NIC ports
        Set<NicDevice> nics = new TreeSet(device.nics());

        // Iterate through the NICs of this device to populate the list
        long portCounter = 0;
        for (NicDevice nic : nics) {
            // The port number of this NIC
            PortNumber portNumber = PortNumber.portNumber(++portCounter);

            // Include the name of this device as an annotation
            DefaultAnnotations.Builder annotations = DefaultAnnotations.builder()
                                .set(AnnotationKeys.PORT_NAME, nic.id());

            // Create a port description and add it to the list
            portDescriptions.add(
                    DefaultPortDescription.builder()
                            .withPortNumber(portNumber)
                            .isEnabled(nic.status())
                            .type(nic.portType())
                            .portSpeed(nic.speed())
                            .annotations(annotations.build())
                            .build());

            log.info(
                "Port discovery on device {}: NIC {} is {} at {} Mbps",
                deviceId, nic.port(), nic.status() ? "up" : "down",
                nic.speed()
            );
        }

        return ImmutableList.copyOf(portDescriptions);
    }

    @Override
    public Collection<PortStatistics> discoverPortStatistics() {
        // Retrieve the device ID
        DeviceId deviceId = getHandler().data().deviceId();
        checkNotNull(deviceId, DEVICE_ID_NULL);

        // Get port statistics for this device
        return getPortStatistics(deviceId);
    }

    /**
     * Query a server to retrieve its port statistics.
     *
     * @param deviceId the device ID to be queried
     * @return list of (per port) PortStatistics
     */
    private Collection<PortStatistics> getPortStatistics(DeviceId deviceId) {
        // List of port statistics to return
        Collection<PortStatistics> portStats = null;

        // Get global monitoring statistics
        MonitoringStatistics monStats = getGlobalMonitoringStatistics(deviceId);
        if (monStats == null) {
            return portStats;
        }

        // Filter out the NIC statistics
        portStats = monStats.nicStatisticsAll();
        if (portStats == null) {
            return portStats;
        }

        log.debug("Port statistics: {}", portStats.toString());

        return portStats;
    }

    @Override
    public Collection<CpuStatistics> discoverCpuStatistics() {
        // Retrieve the device ID
        DeviceId deviceId = getHandler().data().deviceId();
        checkNotNull(deviceId, DEVICE_ID_NULL);

        // Get CPU statistics for this device
        return getCpuStatistics(deviceId);
    }

    /**
     * Query a server to retrieve its CPU statistics.
     *
     * @param deviceId the device ID to be queried
     * @return list of (per core) CpuStatistics
     */
     public Collection<CpuStatistics> getCpuStatistics(DeviceId deviceId) {
        // List of port statistics to return
        Collection<CpuStatistics> cpuStats = null;

        // Get global monitoring statistics
        MonitoringStatistics monStats = getGlobalMonitoringStatistics(deviceId);
        if (monStats == null) {
            return cpuStats;
        }

        // Filter out the CPU statistics
        cpuStats = monStats.cpuStatisticsAll();
        if (cpuStats == null) {
            return cpuStats;
        }

        log.debug("CPU statistics: {}", cpuStats.toString());

        return cpuStats;
    }

    @Override
    public MonitoringStatistics discoverGlobalMonitoringStatistics() {
        // Retrieve the device ID
        DeviceId deviceId = getHandler().data().deviceId();
        checkNotNull(deviceId, DEVICE_ID_NULL);

        // Get global monitoring statistics for this device
        return getGlobalMonitoringStatistics(deviceId);
    }

    /**
     * Query a server to retrieve its global monitoring statistics.
     *
     * @param deviceId the device ID to be queried
     * @return global monitoring statistics
     */
     private MonitoringStatistics getGlobalMonitoringStatistics(DeviceId deviceId) {
        // Monitoring statistics to return
        MonitoringStatistics monStats = null;

        RestServerSBDevice device = null;
        try {
            device = (RestServerSBDevice) getController().getDevice(deviceId);
        } catch (ClassCastException ccEx) {
            log.error(
                "Failed to retrieve global monitoring statistics from device {}",
                deviceId
            );
            return monStats;
        }
        checkNotNull(device, DEVICE_NULL);

        // Hit the path that provides the server's global resources
        InputStream response = null;
        try {
            response = getController().get(
                deviceId,
                GLOBAL_STATS_URL,
                JSON
            );
        } catch (ProcessingException pEx) {
            log.error(
                "Failed to retrieve global monitoring statistics from device {}",
                deviceId
            );
            return monStats;
        }

        // Load the JSON into objects
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> jsonMap = null;
        ObjectNode objNode = null;
        try {
            jsonMap  = mapper.readValue(response, Map.class);
            JsonNode jsonNode = mapper.convertValue(jsonMap, JsonNode.class);
            objNode = (ObjectNode) jsonNode;
        } catch (IOException ioEx) {
            log.error(
                "Failed to retrieve global monitoring statistics from device {}",
                deviceId
            );
            return monStats;
        }

        if (jsonMap == null) {
            log.error(
                "Failed to retrieve global monitoring statistics from device {}",
                deviceId
            );
            return monStats;
        }

        // Get high-level CPU statistics
        int busyCpus = objNode.path(CPU_STATS_BUSY_CPUS).asInt();
        int freeCpus = objNode.path(CPU_STATS_FREE_CPUS).asInt();

        // Get a list of CPU statistics per core
        Collection<CpuStatistics> cpuStats = parseCpuStatistics(deviceId, objNode);

        // Get a list of port statistics
        Collection<PortStatistics> nicStats = parseNicStatistics(deviceId, objNode);

        // Get zero timing statistics
        TimingStatistics timinsgStats = getZeroTimingStatistics();

        // Ready to construct the grand object
        DefaultMonitoringStatistics.Builder statsBuilder =
            DefaultMonitoringStatistics.builder();

        statsBuilder.setDeviceId(deviceId)
                .setTimingStatistics(timinsgStats)
                .setCpuStatistics(cpuStats)
                .setNicStatistics(nicStats)
                .build();

        monStats = statsBuilder.build();

        log.debug("Global monitoring statistics: {}", monStats.toString());

        return monStats;
    }

    @Override
    public MonitoringStatistics discoverMonitoringStatistics(URI tcId) {
        // Retrieve the device ID
        DeviceId deviceId = getHandler().data().deviceId();
        checkNotNull(deviceId, DEVICE_ID_NULL);

        // Get resource-specific monitoring statistics for this device
        return getMonitoringStatistics(deviceId, tcId);
    }

    /**
     * Query a server to retrieve monitoring statistics for a
     * specific resource (i.e., traffic class).
     *
     * @param deviceId the device ID to be queried
     * @param tcId the ID of the traffic class to be monitored
     * @return resource-specific monitoring statistics
     */
     private MonitoringStatistics getMonitoringStatistics(DeviceId deviceId, URI tcId) {
        // Monitoring statistics to return
        MonitoringStatistics monStats = null;

        RestServerSBDevice device = null;
        try {
            device = (RestServerSBDevice) getController().getDevice(deviceId);
        } catch (ClassCastException ccEx) {
            log.error(
                "Failed to retrieve monitoring statistics from device {}",
                deviceId
            );
            return monStats;
        }
        checkNotNull(device, DEVICE_NULL);

        // Create a resource-specific URL
        String scUrl = SERVICE_CHAINS_STATS_URL + "/" + tcId.toString();

        // Hit the path that provides the server's specific resources
        InputStream response = null;
        try {
            response = getController().get(
                deviceId,
                scUrl,
                JSON
            );
        } catch (ProcessingException pEx) {
            log.error(
                "Failed to retrieve monitoring statistics from device {}",
                deviceId
            );
            return monStats;
        }

        // Load the JSON into objects
        ObjectMapper mapper = new ObjectMapper();
        Map<String, Object> jsonMap = null;
        JsonNode jsonNode  = null;
        ObjectNode objNode = null;
        try {
            jsonMap  = mapper.readValue(response, Map.class);
            jsonNode = mapper.convertValue(jsonMap, JsonNode.class);
            objNode = (ObjectNode) jsonNode;
        } catch (IOException ioEx) {
            log.error(
                "Failed to retrieve monitoring statistics from device {}",
                deviceId
            );
            return monStats;
        }

        if (jsonMap == null) {
            log.error(
                "Failed to retrieve monitoring statistics from device {}",
                deviceId
            );
            return monStats;
        }

        // Get the ID of the traffic class
        String id = get(jsonNode, PARAM_ID);

        // And verify that this is the traffic class we want to monitor
        if (!id.equals(tcId.toString())) {
            throw new IllegalStateException(
                "Failed to retrieve monitoring data for traffic class " + tcId +
                ". Traffic class ID does not agree."
            );
        }

        // Get a list of CPU statistics per core
        Collection<CpuStatistics> cpuStats = parseCpuStatistics(deviceId, objNode);

        // Get a list of port statistics
        Collection<PortStatistics> nicStats = parseNicStatistics(deviceId, objNode);

        // Get timing statistics
        TimingStatistics timinsgStats = parseTimingStatistics(objNode);

        // Ready to construct the grand object
        DefaultMonitoringStatistics.Builder statsBuilder =
            DefaultMonitoringStatistics.builder();

        statsBuilder.setDeviceId(deviceId)
                .setTimingStatistics(timinsgStats)
                .setCpuStatistics(cpuStats)
                .setNicStatistics(nicStats)
                .build();

        monStats = statsBuilder.build();

        log.debug("Monitoring statistics: {}", monStats.toString());

        return monStats;
    }

    /**
     * Parse the input JSON object, looking for CPU-related
     * statistics. Upon success, construct and return a list
     * of CPU statistics objects.
     *
     * @param deviceId the device ID that sent the JSON object
     * @param objNode input JSON node with CPU statistics information
     * @return list of (per core) CpuStatistics
     */
    private Collection<CpuStatistics> parseCpuStatistics(
            DeviceId deviceId, JsonNode objNode) {
        Collection<CpuStatistics> cpuStats = Lists.newArrayList();

        if (objNode == null) {
            return cpuStats;
        }

        JsonNode cpuNode = objNode.path(BasicServerDriver.PARAM_CPUS);

        for (JsonNode cn : cpuNode) {
            ObjectNode cpuObjNode = (ObjectNode) cn;

            // CPU ID with its load and status
            int   cpuId    = cpuObjNode.path(CPU_PARAM_ID).asInt();
            float cpuLoad  = cpuObjNode.path(CPU_PARAM_LOAD).floatValue();
            boolean isBusy = cpuObjNode.path(CPU_PARAM_STATUS).booleanValue();

            // Incorporate these statistics into an object
            DefaultCpuStatistics.Builder cpuBuilder =
                DefaultCpuStatistics.builder();

            cpuBuilder.setDeviceId(deviceId)
                    .setId(cpuId)
                    .setLoad(cpuLoad)
                    .setIsBusy(isBusy)
                    .build();

            // We have statistics for this CPU core
            cpuStats.add(cpuBuilder.build());
        }

        return cpuStats;
    }

    /**
     * Parse the input JSON object, looking for NIC-related
     * statistics. Upon success, construct and return a list
     * of NIC statistics objects.
     *
     * @param deviceId the device ID that sent the JSON object
     * @param objNode input JSON node with NIC statistics information
     * @return list of (per port) PortStatistics
     */
    private Collection<PortStatistics> parseNicStatistics(
            DeviceId deviceId, JsonNode objNode) {
        Collection<PortStatistics> nicStats = Lists.newArrayList();

        if (objNode == null) {
            return nicStats;
        }

        JsonNode nicNode = objNode.path(PARAM_NICS);

        for (JsonNode nn : nicNode) {
            ObjectNode nicObjNode = (ObjectNode) nn;

            // All the NIC attributes
            String nicId  = get(nn, NIC_PARAM_ID);
            int port = Integer.parseInt(nicId.replaceAll("\\D+", ""));

            long rxCount   = nicObjNode.path(NIC_STATS_RX_COUNT).asLong();
            long rxBytes   = nicObjNode.path(NIC_STATS_RX_BYTES).asLong();
            long rxDropped = nicObjNode.path(NIC_STATS_RX_DROPS).asLong();
            long rxErrors  = nicObjNode.path(NIC_STATS_RX_ERRORS).asLong();
            long txCount   = nicObjNode.path(NIC_STATS_TX_COUNT).asLong();
            long txBytes   = nicObjNode.path(NIC_STATS_TX_BYTES).asLong();
            long txDropped = nicObjNode.path(NIC_STATS_TX_DROPS).asLong();
            long txErrors  = nicObjNode.path(NIC_STATS_TX_ERRORS).asLong();

            // Incorporate these statistics into an object
            DefaultPortStatistics.Builder nicBuilder =
                DefaultPortStatistics.builder();

            nicBuilder.setDeviceId(deviceId)
                    .setPort(port)
                    .setPacketsReceived(rxCount)
                    .setPacketsSent(txCount)
                    .setBytesReceived(rxBytes)
                    .setBytesSent(txBytes)
                    .setPacketsRxDropped(rxDropped)
                    .setPacketsRxErrors(rxErrors)
                    .setPacketsTxDropped(txDropped)
                    .setPacketsTxErrors(txErrors)
                    .build();

            // We have statistics for this NIC
            nicStats.add(nicBuilder.build());
        }

        return nicStats;
    }

    /**
     * Parse the input JSON object, looking for timing-related
     * statistics. Upon success, construct and return a
     * timing statistics object.
     *
     * @param objNode input JSON node with timing statistics information
     * @return TimingStatistics object or null
     */
    private TimingStatistics parseTimingStatistics(JsonNode objNode) {
        TimingStatistics timinsgStats = null;

        if (objNode == null) {
            return timinsgStats;
        }

        // Get timing statistics
        JsonNode timingNode = objNode.path(PARAM_TIMING_STATS);
        ObjectNode timingObjNode = (ObjectNode) timingNode;

        // Time (ns) to parse the controller's deployment instruction
        long parsingTime = timingObjNode.path(TIMING_PARAM_PARSE).asLong();
        // Time (ns) to do the deployment
        long launchingTime = timingObjNode.path(TIMING_PARAM_LAUNCH).asLong();
        // Total time (ns)
        long totalTime = parsingTime + launchingTime;

        // Get autoscale timing statistics
        JsonNode autoscaleTimingNode = objNode.path(PARAM_TIMING_AUTOSCALE);
        ObjectNode autoscaleTimingObjNode = (ObjectNode) autoscaleTimingNode;

        // Time (ns) to autoscale a server's load
        long autoscaleTime = autoscaleTimingObjNode.path(
            TIMING_PARAM_AUTOSCALE
        ).asLong();

        DefaultTimingStatistics.Builder timingBuilder =
            DefaultTimingStatistics.builder();

        timingBuilder.setParsingTime(parsingTime)
                    .setLaunchingTime(launchingTime)
                    .setAutoscaleTime(autoscaleTime)
                    .build();

        return timingBuilder.build();
    }

    /**
     * Return a timing statistics object with zero counters.
     * This is useful when constructing MonitoringStatistics
     * objects that do not require timers.
     *
     * @return TimingStatistics object
     */
    private TimingStatistics getZeroTimingStatistics() {
        DefaultTimingStatistics.Builder zeroTimingBuilder =
            DefaultTimingStatistics.builder();

        zeroTimingBuilder.setParsingTime(0)
                         .setLaunchingTime(0)
                         .setAutoscaleTime(0)
                         .build();

        return zeroTimingBuilder.build();
    }

}
