/*
 * 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.cli;

import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.onlab.util.Tools;
import org.onosproject.cli.AbstractShellCommand;
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 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;

/**
 * Lists all stats information of control plane metrics.
 */
@Command(scope = "onos", name = "cpman-stats-list",
        description = "Lists control metrics statistics")
public class ControlMetricsStatsListCommand extends AbstractShellCommand {

    private static final String FMT = "metricType=%s, latestValue=%d, " +
            "averageValue=%d, latestTime=%s";
    private static final String INVALID_TYPE = "Invalid control resource type.";

    private static final long TIMEOUT_MILLIS = 3000;

    @Argument(index = 0, name = "node", description = "ONOS node identifier",
            required = true, multiValued = false)
    String node = null;

    @Argument(index = 1, name = "type",
            description = "Resource type (cpu|memory|disk|network|control_message)",
            required = true, multiValued = false)
    String type = null;

    @Argument(index = 2, name = "name", description = "Resource name (or Device Id)",
            required = false, multiValued = false)
    String name = null;

    @Override
    protected void execute() {
        ControlPlaneMonitorService service = get(ControlPlaneMonitorService.class);
        NodeId nodeId = NodeId.nodeId(node);
        switch (type) {
            case "cpu":
                printMetricsStats(service, nodeId, CPU_METRICS);
                break;
            case "memory":
                printMetricsStats(service, nodeId, MEMORY_METRICS);
                break;
            case "disk":
                printMetricsStats(service, nodeId, DISK_METRICS, name);
                break;
            case "network":
                printMetricsStats(service, nodeId, NETWORK_METRICS, name);
                break;
            case "control_message":
                if (name != null) {
                    printMetricsStats(service, nodeId, CONTROL_MESSAGE_METRICS,
                            DeviceId.deviceId(name));
                }
                break;
            default:
                print(INVALID_TYPE);
                break;
        }
    }

    private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
                                   Set<ControlMetricType> typeSet) {
        printMetricsStats(service, nodeId, typeSet, null, null);
    }

    private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
                                   Set<ControlMetricType> typeSet, String resName) {
        printMetricsStats(service, nodeId, typeSet, resName, null);
    }

    private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
                                   Set<ControlMetricType> typeSet, DeviceId did) {
        printMetricsStats(service, nodeId, typeSet, null, did);
    }

    private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
                                   Set<ControlMetricType> typeSet, String resName, DeviceId did) {
        if (resName == null && did == null) {
            typeSet.forEach(s -> {
                CompletableFuture<ControlLoadSnapshot> cf =
                        service.getLoad(nodeId, s, Optional.empty());
                ControlLoadSnapshot cmr =
                        Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
                printRemote(s, cmr);
            });
        } else if (resName == null && did != null) {
            typeSet.forEach(s -> {
                CompletableFuture<ControlLoadSnapshot> cf =
                        service.getLoad(nodeId, s, Optional.of(did));
                ControlLoadSnapshot cmr =
                        Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
                printRemote(s, cmr);
            });
        } else if (resName != null && did == null) {
            typeSet.forEach(s -> {
                CompletableFuture<ControlLoadSnapshot> cf =
                        service.getLoad(nodeId, s, resName);
                ControlLoadSnapshot cmr =
                        Tools.futureGetOrElse(cf, TIMEOUT_MILLIS, TimeUnit.MILLISECONDS, null);
                printRemote(s, cmr);
            });
        }
    }

    private void printRemote(ControlMetricType cmType, ControlLoadSnapshot cls) {
        if (cls != null) {
            print(FMT, cmType.toString(), cls.latest(), cls.average(), cls.time());
        } else {
            print("Failed to retrieve metric value for type {}", cmType.toString());
        }
    }
}
