/*
 * Copyright 2016-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.cpman.rest;

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.apache.commons.lang3.StringUtils;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.NodeId;
import org.onosproject.cpman.ControlLoadSnapshot;
import org.onosproject.cpman.ControlMetricType;
import org.onosproject.cpman.ControlPlaneMonitorService;
import org.onosproject.net.DeviceId;
import org.onosproject.rest.AbstractWebResource;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.Optional;
import java.util.Set;

import static org.onosproject.cpman.ControlResource.CONTROL_MESSAGE_METRICS;
import static org.onosproject.cpman.ControlResource.CPU_METRICS;
import static org.onosproject.cpman.ControlResource.DISK_METRICS;
import static org.onosproject.cpman.ControlResource.MEMORY_METRICS;
import static org.onosproject.cpman.ControlResource.NETWORK_METRICS;
import static org.onosproject.cpman.ControlResource.Type.CONTROL_MESSAGE;
import static org.onosproject.cpman.ControlResource.Type.DISK;
import static org.onosproject.cpman.ControlResource.Type.NETWORK;

/**
 * Query control metrics.
 */
@Path("controlmetrics")
public class ControlMetricsWebResource extends AbstractWebResource {

    private final ControlPlaneMonitorService monitorService =
            get(ControlPlaneMonitorService.class);
    private final ClusterService clusterService = get(ClusterService.class);
    private final NodeId localNodeId = clusterService.getLocalNode().id();
    private final ObjectNode root = mapper().createObjectNode();

    /**
     * Returns control message metrics of all devices.
     *
     * @return array of all control message metrics
     * @onos.rsModel ControlMessageMetrics
     */
    @GET
    @Path("messages")
    @Produces(MediaType.APPLICATION_JSON)
    public Response controlMessageMetrics() {

        ArrayNode deviceNodes = root.putArray("devices");
        monitorService.availableResourcesSync(localNodeId, CONTROL_MESSAGE).forEach(name -> {
            ObjectNode deviceNode = mapper().createObjectNode();
            ObjectNode valueNode = mapper().createObjectNode();

            metricsStats(monitorService, localNodeId, CONTROL_MESSAGE_METRICS,
                    DeviceId.deviceId(name), valueNode);
            deviceNode.put("name", name);
            deviceNode.set("value", valueNode);

            deviceNodes.add(deviceNode);
        });

        return ok(root).build();
    }

    /**
     * Returns control message metrics of a given device.
     *
     * @param deviceId device identification
     * @return control message metrics of a given device
     * @onos.rsModel ControlMessageMetric
     */
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    @Path("messages/{deviceId}")
    public Response controlMessageMetrics(@PathParam("deviceId") String deviceId) {

        metricsStats(monitorService, localNodeId, CONTROL_MESSAGE_METRICS,
                DeviceId.deviceId(deviceId), root);

        return ok(root).build();
    }

    /**
     * Returns cpu metrics.
     *
     * @return cpu metrics
     * @onos.rsModel CpuMetrics
     */
    @GET
    @Path("cpu_metrics")
    @Produces(MediaType.APPLICATION_JSON)
    public Response cpuMetrics() {

        metricsStats(monitorService, localNodeId, CPU_METRICS, root);
        return ok(root).build();
    }

    /**
     * Returns memory metrics.
     *
     * @return memory metrics
     * @onos.rsModel MemoryMetrics
     */
    @GET
    @Path("memory_metrics")
    @Produces(MediaType.APPLICATION_JSON)
    public Response memoryMetrics() {

        metricsStats(monitorService, localNodeId, MEMORY_METRICS, root);
        return ok(root).build();
    }

    /**
     * Returns disk metrics of all resources.
     *
     * @return disk metrics of all resources
     * @onos.rsModel DiskMetrics
     */
    @GET
    @Path("disk_metrics")
    @Produces(MediaType.APPLICATION_JSON)
    public Response diskMetrics() {

        ArrayNode diskNodes = root.putArray("disks");
        monitorService.availableResourcesSync(localNodeId, DISK).forEach(name -> {
            ObjectNode diskNode = mapper().createObjectNode();
            ObjectNode valueNode = mapper().createObjectNode();

            metricsStats(monitorService, localNodeId, DISK_METRICS, name, valueNode);
            diskNode.put("name", name);
            diskNode.set("value", valueNode);

            diskNodes.add(diskNode);
        });

        return ok(root).build();
    }

    /**
     * Returns network metrics of all resources.
     *
     * @return network metrics of all resources
     * @onos.rsModel NetworkMetrics
     */
    @GET
    @Path("network_metrics")
    @Produces(MediaType.APPLICATION_JSON)
    public Response networkMetrics() {

        ArrayNode networkNodes = root.putArray("networks");
        monitorService.availableResourcesSync(localNodeId, NETWORK).forEach(name -> {
            ObjectNode networkNode = mapper().createObjectNode();
            ObjectNode valueNode = mapper().createObjectNode();

            metricsStats(monitorService, localNodeId, NETWORK_METRICS, name, valueNode);
            networkNode.put("name", name);
            networkNode.set("value", valueNode);

            networkNodes.add(networkNode);
        });

        return ok(root).build();
    }

    /**
     * Returns a collection of control message stats.
     *
     * @param service control plane monitoring service
     * @param nodeId  node identification
     * @param typeSet a set of control message types
     * @param did     device identification
     * @param node    object node
     * @return a collection of control message stats
     */
    private ArrayNode metricsStats(ControlPlaneMonitorService service,
                                   NodeId nodeId, Set<ControlMetricType> typeSet,
                                   DeviceId did, ObjectNode node) {
        return metricsStats(service, nodeId, typeSet, null, did, node);
    }

    /**
     * Returns a collection of system metric stats.
     *
     * @param service control plane monitoring service
     * @param nodeId  node identification
     * @param typeSet a set of system metric types
     * @param node    object node
     * @return a collection of system metric stats
     */
    private ArrayNode metricsStats(ControlPlaneMonitorService service,
                                   NodeId nodeId, Set<ControlMetricType> typeSet,
                                   ObjectNode node) {
        return metricsStats(service, nodeId, typeSet, null, null, node);
    }

    /**
     * Returns a collection of system metric stats.
     *
     * @param service      control plane monitoring service
     * @param nodeId       node identification
     * @param typeSet      a set of control message types
     * @param resourceName device identification
     * @param node         object node
     * @return a collection of system metric stats
     */
    private ArrayNode metricsStats(ControlPlaneMonitorService service,
                                   NodeId nodeId, Set<ControlMetricType> typeSet,
                                   String resourceName, ObjectNode node) {
        return metricsStats(service, nodeId, typeSet, resourceName, null, node);
    }

    /**
     * Returns a collection of control loads of the given control metric types.
     *
     * @param service control plane monitoring service
     * @param nodeId  node identification
     * @param typeSet a group of control metric types
     * @param name    resource name
     * @param did     device identification
     * @return a collection of control loads
     */
    private ArrayNode metricsStats(ControlPlaneMonitorService service,
                                   NodeId nodeId, Set<ControlMetricType> typeSet,
                                   String name, DeviceId did, ObjectNode node) {
        ArrayNode metricsNode = node.putArray("metrics");

        if (name == null && did == null) {
            typeSet.forEach(type -> {
                ControlLoadSnapshot cls = service.getLoadSync(nodeId, type, Optional.empty());
                processRest(cls, type, metricsNode);
            });
        } else if (name == null) {
            typeSet.forEach(type -> {
                ControlLoadSnapshot cls = service.getLoadSync(nodeId, type, Optional.of(did));
                processRest(cls, type, metricsNode);
            });
        } else if (did == null) {
            typeSet.forEach(type -> {
                ControlLoadSnapshot cls = service.getLoadSync(nodeId, type, name);
                processRest(cls, type, metricsNode);
            });
        }

        return metricsNode;
    }

    /**
     * Camelizes the input string.
     *
     * @param value              original string
     * @param startWithLowerCase flag that determines whether to use lower case
     *                           for the camelized string
     * @return camelized string
     */
    private String toCamelCase(String value, boolean startWithLowerCase) {
        String[] strings = StringUtils.split(value.toLowerCase(), "_");
        for (int i = startWithLowerCase ? 1 : 0; i < strings.length; i++) {
            strings[i] = StringUtils.capitalize(strings[i]);
        }
        return StringUtils.join(strings);
    }

    /**
     * Transforms control load snapshot object into JSON object.
     *
     * @param cls         control load snapshot
     * @param type        control metric type
     * @param metricsNode array of JSON node
     */
    private void processRest(ControlLoadSnapshot cls, ControlMetricType type, ArrayNode metricsNode) {
        ObjectNode metricNode = mapper().createObjectNode();

        if (cls != null) {
            metricNode.set(toCamelCase(type.toString(), true),
                    codec(ControlLoadSnapshot.class).encode(cls, this));
            metricsNode.add(metricNode);
        }
    }
}
