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

import static com.google.common.collect.Lists.newArrayList;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import org.apache.karaf.shell.commands.Argument;
import org.apache.karaf.shell.commands.Command;
import org.apache.karaf.shell.commands.Option;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.cli.Comparators;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.FlowRuleService;
import org.onosproject.net.flow.TableStatisticsEntry;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;

/**
 * Lists port statistic of all ports in the system.
 */
@Command(scope = "onos", name = "tablestats",
        description = "Lists statistics of all tables in the device")
public class TableStatisticsCommand extends AbstractShellCommand {

    @Option(name = "-t", aliases = "--table", description = "Show human readable table format for statistics",
            required = false, multiValued = false)
    private boolean table = false;

    @Argument(index = 0, name = "uri", description = "Device ID",
            required = false, multiValued = false)
    String uri = null;

    private static final String FORMAT =
            "   table=%s, active=%s, lookedup=%s, matched=%s";

    @Override
    protected void execute() {
        FlowRuleService flowService = get(FlowRuleService.class);
        DeviceService deviceService = get(DeviceService.class);

        SortedMap<Device, List<TableStatisticsEntry>> deviceTableStats =
                getSortedTableStats(deviceService, flowService);

        if (outputJson()) {
            print("%s", json(deviceTableStats.keySet(), deviceTableStats));
        } else {
            deviceTableStats.forEach((device, tableStats) -> printTableStats(device, tableStats));
        }
    }

    /**
     * Produces a JSON array of table statistics grouped by the each device.
     *
     * @param devices     collection of devices
     * @param deviceTableStats collection of table statistics per each device
     * @return JSON array
     */
    private JsonNode json(Iterable<Device> devices,
                          Map<Device, List<TableStatisticsEntry>> deviceTableStats) {
        ObjectMapper mapper = new ObjectMapper();
        ArrayNode result = mapper.createArrayNode();
        for (Device device : devices) {
            result.add(json(mapper, device, deviceTableStats.get(device)));
        }
        return result;
    }

    // Produces JSON object with the table statistics of the given device.
    private ObjectNode json(ObjectMapper mapper,
                            Device device, List<TableStatisticsEntry> tableStats) {
        ObjectNode result = mapper.createObjectNode();
        ArrayNode array = mapper.createArrayNode();

        tableStats.forEach(tableStat -> array.add(jsonForEntity(tableStat, TableStatisticsEntry.class)));

        result.put("device", device.id().toString())
                .put("tableCount", tableStats.size())
                .set("tables", array);
        return result;
    }

    /**
     * Prints flow table statistics.
     *
     * @param d     the device
     * @param tableStats the set of flow table statistics for that device
     */
    protected void printTableStats(Device d,
                                   List<TableStatisticsEntry> tableStats) {
        boolean empty = tableStats == null || tableStats.isEmpty();
        print("deviceId=%s, tableCount=%d", d.id(), empty ? 0 : tableStats.size());
        if (!empty) {
            for (TableStatisticsEntry t : tableStats) {
                print(FORMAT, t.tableId(), t.activeFlowEntries(),
                      t.packetsLookedup(), t.packetsMatched());
            }
        }
    }

    /**
     * Returns the list of table statistics sorted using the device ID URIs and table IDs.
     *
     * @param deviceService device service
     * @param flowService flow rule service
     * @return sorted table statistics list
     */
    protected SortedMap<Device, List<TableStatisticsEntry>> getSortedTableStats(DeviceService deviceService,
                                                          FlowRuleService flowService) {
        SortedMap<Device, List<TableStatisticsEntry>> deviceTableStats = new TreeMap<>(Comparators.ELEMENT_COMPARATOR);
        List<TableStatisticsEntry> tableStatsList;
        Iterable<Device> devices = uri == null ? deviceService.getDevices() :
                Collections.singletonList(deviceService.getDevice(DeviceId.deviceId(uri)));
        for (Device d : devices) {
            tableStatsList = newArrayList(flowService.getFlowTableStatistics(d.id()));
            tableStatsList.sort((p1, p2) -> Integer.valueOf(p1.tableId()).compareTo(Integer.valueOf(p2.tableId())));
            deviceTableStats.put(d, tableStatsList);
        }
        return deviceTableStats;
    }

}
