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

import org.apache.karaf.shell.api.action.Argument;
import org.apache.karaf.shell.api.action.Command;
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 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.";

    @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 doExecute() {
        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;
        }
    }

    /**
     * Prints system metric statistic information.
     *
     * @param service monitor service
     * @param nodeId  node identifier
     * @param typeSet control metric type
     */
    private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
                                   Set<ControlMetricType> typeSet) {
        printMetricsStats(service, nodeId, typeSet, null, null);
    }

    /**
     * Prints disk and network metric statistic information.
     *
     * @param service monitor service
     * @param nodeId  node identifier
     * @param typeSet control metric type
     * @param resName resource name
     */
    private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
                                   Set<ControlMetricType> typeSet, String resName) {
        printMetricsStats(service, nodeId, typeSet, resName, null);
    }

    /**
     * Prints control message metric statistic information.
     *
     * @param service monitor service
     * @param nodeId  node identifier
     * @param typeSet control metric type
     * @param did     device identifier
     */
    private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
                                   Set<ControlMetricType> typeSet, DeviceId did) {
        printMetricsStats(service, nodeId, typeSet, null, did);
    }

    /**
     * Prints control plane metric statistic information.
     *
     * @param service monitor service
     * @param nodeId  node identifier
     * @param typeSet control metric type
     * @param resName resource name
     * @param did     device identifier
     */
    private void printMetricsStats(ControlPlaneMonitorService service, NodeId nodeId,
                                   Set<ControlMetricType> typeSet, String resName, DeviceId did) {
        if (resName == null && did == null) {
            typeSet.forEach(s -> {
                ControlLoadSnapshot cls = service.getLoadSync(nodeId, s, Optional.empty());
                printControlLoadSnapshot(s, cls);
            });
        } else if (resName == null) {
            typeSet.forEach(s -> {
                ControlLoadSnapshot cls = service.getLoadSync(nodeId, s, Optional.of(did));
                printControlLoadSnapshot(s, cls);
            });
        } else if (did == null) {
            typeSet.forEach(s -> {
                ControlLoadSnapshot cls = service.getLoadSync(nodeId, s, resName);
                printControlLoadSnapshot(s, cls);
            });
        }
    }

    /**
     * Prints control load snapshot.
     *
     * @param cmType control metric type
     * @param cls    control load snapshot
     */
    private void printControlLoadSnapshot(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());
        }
    }
}
