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

import com.google.common.base.Preconditions;
import org.apache.karaf.shell.api.action.Command;
import org.apache.karaf.shell.api.action.Option;
import org.apache.karaf.shell.api.action.lifecycle.Service;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.MplsLabel;
import org.onlab.packet.TpPort;
import org.onlab.packet.VlanId;
import org.onosproject.cli.AbstractShellCommand;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.DeviceId;
import org.onosproject.net.PortNumber;
import org.onosproject.net.flow.DefaultTrafficSelector;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.t3.api.StaticPacketTrace;
import org.onosproject.t3.api.TroubleshootService;

import static org.onlab.packet.EthType.EtherType;

/**
 * Starts a Static Packet Trace for a given input and prints the result.
 */
@Service
@Command(scope = "onos", name = "t3-troubleshoot",
        description = "troubleshoots flows and groups between source and destination")
public class TroubleshootTraceCommand extends AbstractShellCommand {


    private static final String FLOW_SHORT_FORMAT = "    %s, bytes=%s, packets=%s, "
            + "table=%s, priority=%s, selector=%s, treatment=%s";

    private static final String GROUP_FORMAT =
            "   id=0x%s, state=%s, type=%s, bytes=%s, packets=%s, appId=%s, referenceCount=%s";
    private static final String GROUP_BUCKET_FORMAT =
            "       id=0x%s, bucket=%s, bytes=%s, packets=%s, actions=%s";

    private static final String CONTROLLER = "CONTROLLER";

    @Option(name = "-v", aliases = "--verbose", description = "Outputs complete path")
    private boolean verbosity1 = false;

    @Option(name = "-vv", aliases = "--veryverbose", description = "Outputs flows and groups for every device")
    private boolean verbosity2 = false;

    @Option(name = "-s", aliases = "--srcIp", description = "Source IP")
    String srcIp = null;

    @Option(name = "-sp", aliases = "--srcPort", description = "Source Port", required = true)
    String srcPort = null;

    @Option(name = "-sm", aliases = "--srcMac", description = "Source MAC")
    String srcMac = null;

    @Option(name = "-et", aliases = "--ethType", description = "ETH Type", valueToShowInHelp = "ipv4")
    String ethType = "ipv4";

    @Option(name = "-stp", aliases = "--srcTcpPort", description = "Source TCP Port")
    String srcTcpPort = null;

    @Option(name = "-d", aliases = "--dstIp", description = "Destination IP")
    String dstIp = null;

    @Option(name = "-dm", aliases = "--dstMac", description = "Destination MAC")
    String dstMac = null;

    @Option(name = "-dtp", aliases = "--dstTcpPort", description = "destination TCP Port")
    String dstTcpPort = null;

    @Option(name = "-vid", aliases = "--vlanId", description = "Vlan of incoming packet", valueToShowInHelp = "None")
    String vlan = "None";

    @Option(name = "-ml", aliases = "--mplsLabel", description = "Mpls label of incoming packet")
    String mplsLabel = null;

    @Option(name = "-mb", aliases = "--mplsBos", description = "MPLS BOS")
    String mplsBos = null;

    @Option(name = "-ipp", aliases = "--ipProto", description = "IP Proto")
    String ipProto = null;

    @Option(name = "-udps", aliases = "--udpSrc", description = "UDP Source")
    String udpSrc = null;

    @Option(name = "-udpd", aliases = "--udpDst", description = "UDP Destination")
    String udpDst = null;

    @Override
    protected void doExecute() {
        TroubleshootService service = get(TroubleshootService.class);
        String[] cpInfo = srcPort.split("/");
        Preconditions.checkArgument(cpInfo.length == 2, "wrong format of source port");
        ConnectPoint cp;
        //Uses input port as a convenience to carry the Controller port, proper flood behaviour is handled in the
        // troubleshoot manager.
        if (cpInfo[1].equalsIgnoreCase(CONTROLLER)) {
            cp = new ConnectPoint(DeviceId.deviceId(cpInfo[0]), PortNumber.CONTROLLER);
        } else {
            cp = ConnectPoint.deviceConnectPoint(srcPort);
        }

        EtherType type = EtherType.valueOf(ethType.toUpperCase());

        //Input Port must be specified
        TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder()
                .matchInPort(cp.port());

        if (srcIp != null) {
            if (type.equals(EtherType.IPV6)) {
                selectorBuilder.matchIPv6Src(IpAddress.valueOf(srcIp).toIpPrefix());
            } else {
                selectorBuilder.matchIPSrc(IpAddress.valueOf(srcIp).toIpPrefix());
            }
        }

        if (srcMac != null) {
            selectorBuilder.matchEthSrc(MacAddress.valueOf(srcMac));
        }

        //if EthType option is not specified using IPv4
        selectorBuilder.matchEthType(type.ethType().toShort());

        if (srcTcpPort != null) {
            selectorBuilder.matchTcpSrc(TpPort.tpPort(Integer.parseInt(srcTcpPort)));
        }

        if (dstIp != null) {
            if (type.equals(EtherType.IPV6)) {
                selectorBuilder.matchIPv6Dst(IpAddress.valueOf(dstIp).toIpPrefix());
            } else {
                selectorBuilder.matchIPDst(IpAddress.valueOf(dstIp).toIpPrefix());
            }
        }

        if (dstMac != null) {
            selectorBuilder.matchEthDst(MacAddress.valueOf(dstMac));
        }
        if (dstTcpPort != null) {
            selectorBuilder.matchTcpDst(TpPort.tpPort(Integer.parseInt(dstTcpPort)));
        }

        //if vlan option is not specified using NONE
        selectorBuilder.matchVlanId(VlanId.vlanId(vlan));

        if (mplsLabel != null) {
            selectorBuilder.matchMplsLabel(MplsLabel.mplsLabel(Integer.parseInt(mplsLabel)));
        }

        if (mplsBos != null) {
            selectorBuilder.matchMplsBos(Boolean.valueOf(mplsBos));
        }

        if (ipProto != null) {
            selectorBuilder.matchIPProtocol(Byte.valueOf(ipProto));
        }

        if (udpSrc != null) {
            selectorBuilder.matchUdpSrc(TpPort.tpPort(Integer.parseInt(udpSrc)));
        }

        if (udpDst != null) {
            selectorBuilder.matchUdpDst(TpPort.tpPort(Integer.parseInt(udpDst)));
        }


        TrafficSelector packet = selectorBuilder.build();

        //Printing the created packet
        print("Tracing packet: %s", packet.criteria());

        //Build the trace
        StaticPacketTrace trace = service.trace(packet, cp);

        print("%s", T3CliUtils.printTrace(trace, verbosity1, verbosity2));

    }
}
