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

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.incubator.net.dpi.DpiStatInfo;
import org.onosproject.incubator.net.dpi.DpiStatistics;
import org.onosproject.incubator.net.dpi.DpiStatisticsManagerService;
import org.onosproject.incubator.net.dpi.FlowStatInfo;
import org.onosproject.incubator.net.dpi.ProtocolStatInfo;
import org.onosproject.incubator.net.dpi.TrafficStatInfo;

import java.util.List;

import static java.lang.Thread.sleep;

/**
 * Fetches DPI statistics list.
 */
@Command(scope = "onos", name = "dpis",
        description = "Fetches the DPI result entries that is received from DPI engine server")
public class DpisListCommand extends AbstractShellCommand {
    @Argument(index = 0, name = "receivedTime", description = "received time: format 'yyyy-MM-dd HH:mm:ss', "
            + "ex:'2016-08-30 10:31:20', default = null(latest time)",
            required = false, multiValued = false)
    String receivedTime = null; // default is latest time

    @Option(name = "-l", aliases = "--latest",
            description = "Show the latest dpi stats result entry",
            required = false, multiValued = false)
    boolean latest = true; // default

    @Option(name = "-d", aliases = "--detectedProtocols",
            description = "Show the detected protocols only for each statistic entry",
            required = false, multiValued = false)
    boolean dProtocols = false; // default

    @Option(name = "-k", aliases = "--knownFlows",
            description = "Show the known flows only for each statistic entry",
            required = false, multiValued = false)
    boolean kFlows = false; // default

    @Option(name = "-u", aliases = "--unknownFlows",
            description = "Show the unknown flows only for each statistic entry",
            required = false, multiValued = false)
    boolean uFlows = false; // default

    @Option(name = "-a", aliases = "--all",
            description = "Show the all statistics information in detail for each statistic entry",
            required = false, multiValued = false)
    boolean all = false; // default is traffic statistics only display

    @Option(name = "-p", aliases = "--permanent",
            description = "Show the latest dpi stats result entry permanently at 5 second, use Ctrl+C for quitting",
            required = false, multiValued = false)
    boolean permanent = false;

    @Option(name = "-n", aliases = "--lastn",
            description = "Show the last N Dpi stats result entries, MAX_REQUEST_ENTRY = 100",
            required = false, multiValued = false)
    String lastn = null;

    @Option(name = "-P", aliases = "--topnProtocols",
            description = "Show the topn detected Protocol result entries, MAX_PROTOCOLS_TOPN = 100",
            required = false, multiValued = false)
    String topnProtocols = null;

    @Option(name = "-F", aliases = "--topnFlows",
            description = "Show the topn known and unknown Flows result entries, MAX_FLOWS_TOPN = 100",
            required = false, multiValued = false)
    String topnFlows = null;

    private static final int DEFAULT_LASTN = 100;
    private static final int DEFAULT_TOPNP = -1;
    private static final int DEFAULT_TOPNF = -1;
    private static final String NO_DPI_ENTRY_ERROR_MSG = "No DPI statistic entry,"
                                                        + " please check remote DPI engine is running";
    private static final String RECEIVED_TIME_ERROR_MSG = NO_DPI_ENTRY_ERROR_MSG + "\n"
                    + " or correct receivedTime format: 'yyyy-MM-dd HH:mm:ss', ex:'2016-08-30 10:31:20'";

    @Override
    protected void execute() {
        DpiStatisticsManagerService dsms = get(DpiStatisticsManagerService.class);

        DpiStatistics ds;

        int topnP = DEFAULT_TOPNP;
        int topnF = DEFAULT_TOPNF;

        if (topnProtocols != null) {
            topnP = parseIntWithDefault(topnProtocols, DEFAULT_TOPNP);
            if (topnP <= 0) {
                print("Invalid detected protocol topn number: 0 < valid number <= 100");
                return;
            }
        }

        if (topnFlows != null) {
            topnF = parseIntWithDefault(topnFlows, DEFAULT_TOPNF);
            if (topnF <= 0) {
                print("Invalid known or unknown flows topn number: 0 < valid number <= 100");
                return;
            }
        }

        boolean isTopn = (topnP > 0 || topnF > 0);

        if (all) {
            dProtocols = true;
            kFlows = true;
            uFlows = true;
        }

        if (receivedTime != null) {
            if (isTopn) {
                ds = dsms.getDpiStatistics(receivedTime, topnP, topnF);
            } else {
                ds = dsms.getDpiStatistics(receivedTime);
            }
            if (ds == null) {
                print(RECEIVED_TIME_ERROR_MSG);
                return;
            }

            printDpiStatistics(0, ds);
        } else if (lastn != null) {
            int lastN = parseIntWithDefault(lastn, DEFAULT_LASTN);

            List<DpiStatistics> dsList;
            if (isTopn) {
                dsList = dsms.getDpiStatistics(lastN, topnP, topnF);

            } else {
                dsList = dsms.getDpiStatistics(lastN);
            }

            printDpiStatisticsList(dsList);
        } else if (permanent) {
            int i = 0;
            while (true) {
                try {
                    if (isTopn) {
                        ds = dsms.getDpiStatisticsLatest(topnP, topnF);
                    } else {
                        ds = dsms.getDpiStatisticsLatest();
                    }
                    if (ds == null) {
                        print(NO_DPI_ENTRY_ERROR_MSG);
                        return;
                    }

                    printDpiStatistics(i++, ds);
                    sleep(5000);
                } catch (Exception e) {
                    return;
                }
            }
        } else { // latest == true
            if (isTopn) {
                ds = dsms.getDpiStatisticsLatest(topnP, topnF);
            } else {
                ds = dsms.getDpiStatisticsLatest();
            }
            if (ds == null) {
                print(NO_DPI_ENTRY_ERROR_MSG);
                return;
            }

            printDpiStatistics(0, ds);
        }
    }


    /**
     * Parse unsigned integer from input lastn string.
     *
     * @param lastN string lastn number
     * @param defaultN integer default lastn number = 100
     * @return integer lastN number, defaultN if input format is not a number
     */
    private int parseIntWithDefault(String lastN, int defaultN) {
        try {
            lastN = lastN.trim();
            return Integer.parseUnsignedInt(lastN);
        } catch (NumberFormatException e) {
            return defaultN;
        }
    }

    private void printDpiStatistics(int number, DpiStatistics ds) {
        if (outputJson()) {
            printDpiStatisticsJson(number, ds);
        } else {
            printDpiStatisticsClass(number, ds);
        }
    }

    private void printDpiStatisticsJson(int number, DpiStatistics ds) {
        String index = number < 0 ? "  -  " : String.format("%5d", number);
        if ("".equals(ds.receivedTime())) {
            print("ReceivedTime is null, No valid DPI Statistics!");
            return;
        }

        print("<--- (%s) DPI Statistics Time [%s] --->", index, ds.receivedTime());
        print("      %s", ds.toString());
        print("<--------------------------------------------------------->");
    }

    private void printDpiStatisticsClass(int number, DpiStatistics ds) {
        String printLine = "";
        String index = number < 0 ? "  -  " : String.format("%5d", number);

        DpiStatInfo dsi = ds.dpiStatInfo();
        if (dsi == null) {
            return;
        }

        if ("".equals(ds.receivedTime())) {
            print("ReceivedTime is null, No valid DPI Statistics!");
            return;
        }

        print("<--- (%s) DPI Statistics Time [%s] --->", index, ds.receivedTime());

        print("Traffic Statistics:");
        TrafficStatInfo tsi = dsi.trafficStatistics();

        printLine = String.format("        %-30s %-30s", "ethernet.bytes:" + ":", tsi.ethernetBytes());
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "discarded.bytes" + ":", tsi.discardedBytes());
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "ip.packets" + ":", tsi.ipPackets());
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "total.packets" + ":", tsi.totalPackets());
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "ip.bytes" + ":", tsi.ipBytes());
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "avg.pkt.size" + ":", tsi.avgPktSize());
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "unique.flows" + ":", tsi.uniqueFlows());
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "tcp.packets" + ":", tsi.tcpPackets());
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "udp.packets" + ":", tsi.tcpPackets());
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "dpi.throughput.pps" + ":",
                                  tsi.dpiThroughputPps() + " pps");
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "dpi.throughput.bps" + ":",
                                  tsi.dpiThroughputBps() + " bps");
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "traffic.throughput.pps" + ":",
                                  tsi.trafficThroughputPps() + " pps");
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "traffic.throughput.bps" + ":",
                                  tsi.trafficThroughputBps() + " bps");
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "traffic.duration.sec" + ":",
                                  tsi.trafficDurationSec() + " sec");
        print("%s", printLine);
        printLine = String.format("        %-30s %-30s", "guessed.flow.protos" + ":", tsi.guessedFlowProtos());
        print("%s", printLine);

        if (dProtocols || topnProtocols != null) {
            print("");
            print("Detected Protocols:");
            List<ProtocolStatInfo> psiList = dsi.detectedProtos();
            if (psiList != null) {
                psiList.forEach(psi -> print(makeProtocolString(psi)));
            }
        }

        List<FlowStatInfo> fsiList;
        if (kFlows || topnFlows != null) {
            print("");
            print("Known Flows:");
            fsiList = dsi.knownFlows();
            if (fsiList != null) {
                for (int i = 0; i < fsiList.size(); i++) {
                    print(makeFlowString(fsiList.get(i), i));
                }
            }
        }

        if (uFlows || topnFlows != null) {
            print("");
            print("Unknown Flows:");
            fsiList = dsi.unknownFlows();
            if (fsiList != null) {
                for (int i = 0; i < fsiList.size(); i++) {
                    print(makeFlowString(fsiList.get(i), i));
                }
            }
        }

        print("<--------------------------------------------------------->");
    }

    private void printDpiStatisticsList(List<DpiStatistics> dsList) {
        if (outputJson()) {
            printDpiStatisticsListJson(dsList);
        } else {
            printDpiStatisticsListClass(dsList);
        }
    }

    private void printDpiStatisticsListJson(List<DpiStatistics> dsList) {
        for (int i = 0; i < dsList.size(); i++) {
            printDpiStatisticsJson(i, dsList.get(i));
        }
    }

    private void printDpiStatisticsListClass(List<DpiStatistics> dsList) {
        for (int i = 0; i < dsList.size(); i++) {
            printDpiStatisticsClass(i, dsList.get(i));
        }
    }

    private String makeProtocolString(ProtocolStatInfo psi) {
        StringBuffer sb = new StringBuffer("        ");

        sb.append(String.format("%-20s", psi.name()));
        sb.append(String.format(" %s: %-20s", "packets", psi.packets()));
        sb.append(String.format(" %s: %-20s", "bytes", psi.bytes()));
        sb.append(String.format(" %s: %-20s", "flows", psi.flows()));

        return sb.toString();
    }

    private String makeFlowString(FlowStatInfo fsi, int index) {
        StringBuffer sb = new StringBuffer("        ");

        sb.append(String.format("%-8d ", index));
        sb.append(String.format("%s ", fsi.protocol()));
        sb.append(String.format("%s", fsi.hostAName()));
        sb.append(String.format(":%s", fsi.hostAPort()));
        sb.append(String.format(" <-> %s", fsi.hostBName()));
        sb.append(String.format(":%s", fsi.hostBPort()));
        sb.append(String.format(" [proto: %d", fsi.detectedProtocol()));
        sb.append(String.format("/%s]", fsi.detectedProtocolName()));
        sb.append(String.format(" [%s pkts/", fsi.packets()));
        sb.append(String.format("%s bytes]", fsi.bytes()));
        String serverHostName = fsi.hostServerName();
        if (serverHostName != null && !"".equals(serverHostName)) {
            sb.append(String.format("[Host: %s]", serverHostName));
        }

        return sb.toString();
    }
}
