# Copyright (c) 2022 Intel and/or its affiliates.
# 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.

from vpp_papi.vpp_papi import VPPApiClient
import sys, getopt
import packetforge
import fnmatch
import os

# Get VPP json API file directory
CLIENT_ID = "Vppclient"
VPP_JSON_DIR = (
    os.path.abspath("../..") + "/build-root/install-vpp-native/vpp/share/vpp/api/core"
)
VPP_JSON_DIR_PLUGIN = (
    os.path.abspath("../..")
    + "/build-root/install-vpp-native/vpp/share/vpp/api/plugins"
)
API_FILE_SUFFIX = "*.api.json"


def load_json_api_files(suffix=API_FILE_SUFFIX):
    jsonfiles = []
    json_dir = VPP_JSON_DIR
    for root, dirnames, filenames in os.walk(json_dir):
        for filename in fnmatch.filter(filenames, suffix):
            jsonfiles.append(os.path.join(json_dir, filename))
    json_dir = VPP_JSON_DIR_PLUGIN
    for root, dirnames, filenames in os.walk(json_dir):
        for filename in fnmatch.filter(filenames, suffix):
            jsonfiles.append(os.path.join(json_dir, filename))
    if not jsonfiles:
        raise RuntimeError("Error: no json api files found")
    else:
        print("load json api file done")
    return jsonfiles


def connect_vpp(jsonfiles):
    vpp = VPPApiClient(apifiles=jsonfiles)
    r = vpp.connect("CLIENT_ID")
    print("VPP api opened with code: %s" % r)
    return vpp


def Main(argv):
    file_flag = False
    operation = None
    actions = ""
    iface = ""
    try:
        opts, args = getopt.getopt(
            argv,
            "hf:p:a:i:I:",
            [
                "help",
                "add",
                "del",
                "show",
                "file=",
                "pattern=",
                "actions=",
                "interface=",
                "flow-index=",
            ],
        )
    except getopt.GetoptError:
        print(
            "flow_create.py --add|del|show -f <file> -p <pattern> -a <actions> -i <interface> -I <flow-index>"
        )
        sys.exit()
    for opt, arg in opts:
        if opt == "-h":
            print(
                "flow_create.py --add|del|show -f <file> -p <pattern> -a <actions> -i <interface> -I <flow-index>"
            )
            sys.exit()
        elif opt == "--add":
            operation = "add"
        elif opt == "--del":
            operation = "del"
        elif opt == "--show":
            operation = "show"
        elif opt in ("-f", "--file"):
            json_file = arg
            file_flag = True
        elif opt in ("-p", "--pattern") and not file_flag:
            pattern = arg
        elif opt in ("-a", "--actions"):
            actions = arg
        elif opt in ("-i", "--interface"):
            iface = arg
        elif opt in ("-I", "--flow-index"):
            flow_index = arg

    if operation == None:
        print("Error: Please choose the operation: add or del")
        sys.exit()

    if operation == "show":
        if not file_flag:
            result = packetforge.Forge(pattern, actions, False, True)
        else:
            result = packetforge.Forge(json_file, actions, True, True)
        return result, None, operation, None, None

    # Python API need json definitions to interpret messages
    vpp = connect_vpp(load_json_api_files())

    # set inteface states
    vpp.api.sw_interface_set_flags(sw_if_index=int(iface), flags=1)

    if operation == "add":
        if not file_flag:
            result = packetforge.Forge(pattern, actions, False, False)
        else:
            result = packetforge.Forge(json_file, actions, True, False)
        return result, int(iface), operation, None, vpp
    elif operation == "del":
        return None, int(iface), operation, int(flow_index), vpp


if __name__ == "__main__":
    # Parse the arguments
    my_flow, iface, operation, del_flow_index, vpp = Main(sys.argv[1:])

    # if operation is show, just show spec and mask, then exit
    if operation == "show":
        print(my_flow)
        sys.exit()

    if operation == "add":
        # add flow
        rv = vpp.api.flow_add_v2(flow=my_flow)
        flow_index = rv[3]
        print(rv)

        # enable added flow
        rv = vpp.api.flow_enable(flow_index=flow_index, hw_if_index=iface)
        ena_res = rv[2]
        # if enable flow fail, delete added flow
        if ena_res:
            print("Error: enable flow failed, delete flow")
            rv = vpp.api.flow_del(flow_index=flow_index)
        print(rv)

    elif operation == "del":
        # disable flow
        rv = vpp.api.flow_disable(flow_index=del_flow_index, hw_if_index=iface)
        dis_res = rv[2]
        if dis_res:
            print("Error: disable flow failed")
            sys.exit()
        print(rv)

        # delete flow
        rv = vpp.api.flow_del(flow_index=del_flow_index)
        print(rv)

# command example:
# python flow_create.py --add -p "mac()/ipv4(src=1.1.1.1,dst=2.2.2.2)/udp()" -a "redirect-to-queue 3" -i 1
# python flow_create.py --del -i 1 -I 0
# python flow_create.py --show -p "mac()/ipv4(src=1.1.1.1,dst=2.2.2.2)/udp()"
