/*
 * Copyright 2016-present Open Networking Laboratory
 *
 * 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.onlab.util.Tools;
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 java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;

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();
    private static final long TIMEOUT_MILLIS = 1000;

    /**
     * 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.availableResources(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.availableResources(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.availableResources(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 -> {
                ObjectNode metricNode = mapper().createObjectNode();
                CompletableFuture<ControlLoadSnapshot> cf =
                        service.getLoad(nodeId, type, Optional.empty());

                if (cf != null) {
                    ControlLoadSnapshot cmr =
                            Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);

                    if (cmr != null) {
                        metricNode.set(toCamelCase(type.toString(), true),
                                codec(ControlLoadSnapshot.class).encode(cmr, this));
                        metricsNode.add(metricNode);
                    }
                }
            });
        } else if (name == null) {
            typeSet.forEach(type -> {
                ObjectNode metricNode = mapper().createObjectNode();
                CompletableFuture<ControlLoadSnapshot> cf =
                        service.getLoad(nodeId, type, Optional.of(did));

                if (cf != null) {
                    ControlLoadSnapshot cmr =
                            Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
                    if (cmr != null) {
                        metricNode.set(toCamelCase(type.toString(), true),
                                codec(ControlLoadSnapshot.class).encode(cmr, this));
                        metricsNode.add(metricNode);
                    }
                }

            });
        } else if (did == null) {
            typeSet.forEach(type -> {
                ObjectNode metricNode = mapper().createObjectNode();
                CompletableFuture<ControlLoadSnapshot> cf =
                        service.getLoad(nodeId, type, name);

                if (cf != null) {
                    ControlLoadSnapshot cmr =
                            Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
                    if (cmr != null) {
                        metricNode.set(toCamelCase(type.toString(), true),
                                codec(ControlLoadSnapshot.class).encode(cmr, this));
                        metricsNode.add(metricNode);
                    }
                }
            });
        }

        return metricsNode;
    }

    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);
    }
}
