#!/usr/bin/env python3

# Copyright (c) 2016 Cisco and/or its affiliates.
# Copyright (c) 2018 Vinci Consulting Corp.  All rights reserved.
# 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.

"""VPP Configuration Main Entry"""
from __future__ import absolute_import, division, print_function

import re
import os
import sys
import logging
import argparse

from vpplib.AutoConfig import AutoConfig
from vpplib.VPPUtil import VPPUtil

#  Python2/3 compatible
try:
    input = raw_input  # noqa
except NameError:
    pass

VPP_DRYRUNDIR = "/vpp/vpp-config/dryrun"
VPP_AUTO_CONFIGURATION_FILE = "/vpp/vpp-config/configs/auto-config.yaml"
VPP_HUGE_PAGE_FILE = "/vpp/vpp-config/dryrun/sysctl.d/80-vpp.conf"
VPP_STARTUP_FILE = "/vpp/vpp-config/dryrun/vpp/startup.conf"
VPP_GRUB_FILE = "/vpp/vpp-config/dryrun/default/grub"
VPP_REAL_HUGE_PAGE_FILE = "/etc/sysctl.d/80-vpp.conf"
VPP_REAL_STARTUP_FILE = "/etc/vpp/startup.conf"
VPP_REAL_GRUB_FILE = "/etc/default/grub"

rootdir = ""


def autoconfig_yn(question, default):
    """
    Ask the user a yes or no question.

    :param question: The text of the question
    :param default: Value to be returned if '\n' is entered
    :type question: string
    :type default: string
    :returns: The Answer
    :rtype: string
    """
    input_valid = False
    default = default.lower()
    answer = ""
    while not input_valid:
        answer = input(question)
        if len(answer) == 0:
            answer = default
        if re.findall(r"[YyNn]", answer):
            input_valid = True
            answer = answer[0].lower()
        else:
            print("Please answer Y, N or Return.")

    return answer


def autoconfig_cp(node, src, dst):
    """
    Copies a file, saving the original if needed.

    :param node: Node dictionary with cpuinfo.
    :param src: Source File
    :param dst: Destination file
    :type node: dict
    :type src: string
    :type dst: string
    :raises RuntimeError: If command fails
    """

    # If the destination file exist, create a copy if one does not already
    # exist
    ofile = dst + ".orig"
    (ret, stdout, stderr) = VPPUtil.exec_command("ls {}".format(dst))
    if ret == 0:
        cmd = "cp {} {}".format(dst, ofile)
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError(
                "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
            )

    # Copy the source file
    cmd = "cp {} {}".format(src, os.path.dirname(dst))
    (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
    if ret != 0:
        raise RuntimeError("{} failed on node {} {}".format(cmd, node["host"], stderr))


def autoconfig_diff(node, src, dst):
    """
    Returns the diffs of 2 files.

    :param node: Node dictionary with cpuinfo.
    :param src: Source File
    :param dst: Destination file
    :type node: dict
    :type src: string
    :type dst: string
    :returns: The Answer
    :rtype: string
    :raises RuntimeError: If command fails
    """

    # Diff the files and return the output
    cmd = "diff {} {}".format(src, dst)
    (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
    if stderr != "":
        raise RuntimeError(
            "{} failed on node {} {} {}".format(cmd, node["host"], ret, stderr)
        )

    return stdout


def autoconfig_show_system():
    """
    Shows the system information.

    """

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)

    acfg.discover()

    acfg.sys_info()


def autoconfig_hugepage_apply(node, ask_questions=True):
    """
    Apply the huge page configuration.
    :param node: The node structure
    :type node: dict
    :param ask_questions: When True ask the user questions
    :type ask_questions: bool
    :returns: -1 if the caller should return, 0 if not
    :rtype: int

    """

    diffs = autoconfig_diff(node, VPP_REAL_HUGE_PAGE_FILE, rootdir + VPP_HUGE_PAGE_FILE)
    if diffs != "":
        print("These are the changes we will apply to")
        print("the huge page file ({}).\n".format(VPP_REAL_HUGE_PAGE_FILE))
        print(diffs)
        if ask_questions:
            answer = autoconfig_yn(
                "\nAre you sure you want to apply these changes [Y/n]? ", "y"
            )
            if answer == "n":
                return -1

        # Copy and sysctl
        autoconfig_cp(node, rootdir + VPP_HUGE_PAGE_FILE, VPP_REAL_HUGE_PAGE_FILE)
        cmd = "sysctl -p {}".format(VPP_REAL_HUGE_PAGE_FILE)
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError(
                "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
            )
    else:
        print("\nThere are no changes to the huge page configuration.")

    return 0


def autoconfig_vpp_apply(node, ask_questions=True):
    """
    Apply the vpp configuration.

    :param node: The node structure
    :type node: dict
    :param ask_questions: When True ask the user questions
    :type ask_questions: bool
    :returns: -1 if the caller should return, 0 if not
    :rtype: int

    """

    diffs = autoconfig_diff(node, VPP_REAL_STARTUP_FILE, rootdir + VPP_STARTUP_FILE)
    if diffs != "":
        print("These are the changes we will apply to")
        print("the VPP startup file ({}).\n".format(VPP_REAL_STARTUP_FILE))
        print(diffs)
        if ask_questions:
            answer = autoconfig_yn(
                "\nAre you sure you want to apply these changes [Y/n]? ", "y"
            )
            if answer == "n":
                return -1

        # Copy the VPP startup
        autoconfig_cp(node, rootdir + VPP_STARTUP_FILE, VPP_REAL_STARTUP_FILE)
    else:
        print("\nThere are no changes to VPP startup.")

    return 0


def autoconfig_grub_apply(node, ask_questions=True):
    """
    Apply the grub configuration.

    :param node: The node structure
    :type node: dict
    :param ask_questions: When True ask the user questions
    :type ask_questions: bool
    :returns: -1 if the caller should return, 0 if not
    :rtype: int

    """

    print("\nThe configured grub cmdline looks like this:")
    configured_cmdline = node["grub"]["default_cmdline"]
    current_cmdline = node["grub"]["current_cmdline"]
    print(configured_cmdline)
    print("\nThe current boot cmdline looks like this:")
    print(current_cmdline)
    if ask_questions:
        question = "\nDo you want to keep the current boot cmdline [Y/n]? "
        answer = autoconfig_yn(question, "y")
        if answer == "y":
            return

    node["grub"]["keep_cmdline"] = False

    # Diff the file
    diffs = autoconfig_diff(node, VPP_REAL_GRUB_FILE, rootdir + VPP_GRUB_FILE)
    if diffs != "":
        print("These are the changes we will apply to")
        print("the GRUB file ({}).\n".format(VPP_REAL_GRUB_FILE))
        print(diffs)
        if ask_questions:
            answer = autoconfig_yn(
                "\nAre you sure you want to apply these changes [y/N]? ", "n"
            )
            if answer == "n":
                return -1

        # Copy and update grub
        autoconfig_cp(node, rootdir + VPP_GRUB_FILE, VPP_REAL_GRUB_FILE)
        distro = VPPUtil.get_linux_distro()
        if distro[0] == "Ubuntu":
            cmd = "update-grub"
        else:
            cmd = "grub2-mkconfig -o /boot/grub2/grub.cfg"

        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError(
                "{} failed on node {} {} {}".format(cmd, node["host"], stdout, stderr)
            )

        print("There have been changes to the GRUB config a", end=" ")
        print("reboot will be required.")
        return -1
    else:
        print("\nThere are no changes to the GRUB config.")

    return 0


def autoconfig_apply(ask_questions=True):
    """
    Apply the configuration.

    Show the diff of the dryrun file and the actual configuration file
    Copy the files from the dryrun directory to the actual file.
    Peform the system function

    :param ask_questions: When true ask the user questions
    :type ask_questions: bool

    """

    vutil = VPPUtil()
    pkgs = vutil.get_installed_vpp_pkgs()
    if len(pkgs) == 0:
        print("\nVPP is not installed, Install VPP with option 4.")
        return

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)

    if ask_questions:
        print("\nWe are now going to configure your system(s).\n")
        answer = autoconfig_yn("Are you sure you want to do this [Y/n]? ", "y")
        if answer == "n":
            return

    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]

        # Check the system resources
        if not acfg.min_system_resources(node):
            return

        # Stop VPP
        VPPUtil.stop(node)

        # Huge Pages
        ret = autoconfig_hugepage_apply(node, ask_questions)
        if ret != 0:
            return

        # VPP
        ret = autoconfig_vpp_apply(node, ask_questions)
        if ret != 0:
            return

        # Grub
        ret = autoconfig_grub_apply(node, ask_questions)
        if ret != 0:
            # We can still start VPP, even if we haven't configured grub
            VPPUtil.start(node)
            return

        # Everything is configured start vpp
        VPPUtil.start(node)


def autoconfig_dryrun(ask_questions=True):
    """
    Execute the dryrun function.

    :param ask_questions: When true ask the user for paraameters
    :type ask_questions: bool

    """

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE, clean=True)

    # Stop VPP on each node
    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]
        VPPUtil.stop(node)

    # Discover
    acfg.discover()

    # Check the system resources
    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]
        if not acfg.min_system_resources(node):
            return

    # Modify the devices
    if ask_questions:
        acfg.modify_devices()
    else:
        acfg.update_interfaces_config()

    # If there are no interfaces, just return
    for i in nodes.items():
        node = i[1]
        if not acfg.has_interfaces(node):
            print(
                "\nThere are no VPP interfaces configured, please configure at least 1."
            )
            return

    # Modify CPU
    acfg.modify_cpu(ask_questions)

    # Calculate the cpu parameters
    acfg.calculate_cpu_parameters()

    # Acquire TCP stack parameters
    if ask_questions:
        acfg.acquire_tcp_params()

    # Apply the startup
    acfg.apply_vpp_startup()

    # Apply the grub configuration
    acfg.apply_grub_cmdline()

    # Huge Pages
    if ask_questions:
        acfg.modify_huge_pages()
    acfg.apply_huge_pages()


def autoconfig_install():
    """
    Install or Uninstall VPP.

    """

    # Since these commands will take a while, we
    # want to see the progress
    logger = logging.getLogger()

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
    vutil = VPPUtil()

    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]

        pkgs = vutil.get_installed_vpp_pkgs()

        if len(pkgs) > 0:
            print("\nThese packages are installed on node {}".format(node["host"]))
            print("{:25} {}".format("Name", "Version"))
            for pkg in pkgs:
                try:
                    print("{:25} {}".format(pkg["name"], pkg["version"]))
                except KeyError:
                    print("{}".format(pkg["name"]))

            question = "\nDo you want to uninstall these "
            question += "packages [y/N]? "
            answer = autoconfig_yn(question, "n")
            if answer == "y":
                logger.setLevel(logging.INFO)
                vutil.uninstall_vpp(node)
        else:
            print("\nThere are no VPP packages on node {}.".format(node["host"]))
            question = "Do you want to install VPP [Y/n]? "
            answer = autoconfig_yn(question, "y")
            if answer == "y":
                question = "Do you want to install the release version [Y/n]? "
                answer = autoconfig_yn(question, "y")
                if answer == "y":
                    branch = "release"
                else:
                    branch = "master"
                logger.setLevel(logging.INFO)
                vutil.install_vpp(node, branch)

    # Set the logging level back
    logger.setLevel(logging.ERROR)


def autoconfig_patch_qemu():
    """
    Patch the correct qemu version that is needed for openstack

    """

    # Since these commands will take a while, we
    # want to see the progress
    logger = logging.getLogger()

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)

    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]

        logger.setLevel(logging.INFO)
        acfg.patch_qemu(node)


def autoconfig_ipv4_setup():
    """
    Setup IPv4 interfaces

    """

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
    acfg.ipv4_interface_setup()


def autoconfig_create_iperf_vm():
    """
    Setup IPv4 interfaces

    """

    acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
    acfg.destroy_iperf_vm("iperf-server")
    acfg.create_and_bridge_iperf_virtual_interface()
    acfg.create_iperf_vm("iperf-server")


def autoconfig_not_implemented():
    """
    This feature is not implemented

    """

    print("\nThis Feature is not implemented yet....")


def autoconfig_basic_test_menu():
    """
    The auto configuration basic test menu

    """

    basic_menu_text = "\nWhat would you like to do?\n\n\
1) List/Create Simple IPv4 Setup\n\
2) Create an iperf VM and Connect to VPP an interface\n\
9 or q) Back to main menu."

    print("{}".format(basic_menu_text))

    input_valid = False
    answer = ""
    while not input_valid:
        answer = input("\nCommand: ")
        if len(answer) > 1:
            print("Please enter only 1 character.")
            continue
        if re.findall(r"[Qq1-29]", answer):
            input_valid = True
            answer = answer[0].lower()
        else:
            print("Please enter a character between 1 and 2 or 9.")

        if answer == "9":
            answer = "q"

    return answer


def autoconfig_basic_test():
    """
    The auto configuration basic test menu

    """
    vutil = VPPUtil()
    pkgs = vutil.get_installed_vpp_pkgs()
    if len(pkgs) == 0:
        print("\nVPP is not installed, install VPP with option 4.")
        return

    answer = ""
    while answer != "q":
        answer = autoconfig_basic_test_menu()
        if answer == "1":
            autoconfig_ipv4_setup()
        elif answer == "2":
            autoconfig_create_iperf_vm()
        elif answer == "9" or answer == "q":
            return
        else:
            autoconfig_not_implemented()


def autoconfig_main_menu():
    """
    The auto configuration main menu

    """

    main_menu_text = "\nWhat would you like to do?\n\n\
1) Show basic system information\n\
2) Dry Run (Saves the configuration files in {}/vpp/vpp-config/dryrun.\n\
3) Full configuration (WARNING: This will change the system configuration)\n\
4) List/Install/Uninstall VPP.\n\
q) Quit".format(
        rootdir, rootdir
    )

    # 5) Dry Run from {}/vpp/vpp-config/auto-config.yaml (will not ask questions).\n\
    # 6) Install QEMU patch (Needed when running openstack).\n\

    print("{}".format(main_menu_text))

    input_valid = False
    answer = ""
    while not input_valid:
        answer = input("\nCommand: ")
        if len(answer) > 1:
            print("Please enter only 1 character.")
            continue
        if re.findall(r"[Qq1-4]", answer):
            input_valid = True
            answer = answer[0].lower()
        else:
            print("Please enter a character between 1 and 4 or q.")

    return answer


def autoconfig_main():
    """
    The auto configuration main entry point

    """

    # Setup
    autoconfig_setup()

    answer = ""
    while answer != "q":
        answer = autoconfig_main_menu()
        if answer == "1":
            autoconfig_show_system()
        elif answer == "2":
            autoconfig_dryrun()
        elif answer == "3":
            autoconfig_apply()
        elif answer == "4":
            autoconfig_install()
        elif answer == "q":
            return
        else:
            autoconfig_not_implemented()


def autoconfig_setup(ask_questions=True):
    """
    The auto configuration setup function.

    We will copy the configuration files to the dryrun directory.

    """

    global rootdir

    distro = VPPUtil.get_linux_distro()
    if distro[0] == "Ubuntu":
        rootdir = "/usr/local"
    else:
        rootdir = "/usr"

    # If there is a system configuration file use that, if not use the initial auto-config file
    filename = rootdir + VPP_AUTO_CONFIGURATION_FILE
    if os.path.isfile(filename) is True:
        acfg = AutoConfig(rootdir, VPP_AUTO_CONFIGURATION_FILE)
    else:
        raise RuntimeError(
            "The Auto configuration file does not exist {}".format(filename)
        )

    if ask_questions:
        print("\nWelcome to the VPP system configuration utility")

        print("\nThese are the files we will modify:")
        print("    /etc/vpp/startup.conf")
        print("    /etc/sysctl.d/80-vpp.conf")
        print("    /etc/default/grub")

        print(
            "\nBefore we change them, we'll create working copies in "
            "{}".format(rootdir + VPP_DRYRUNDIR)
        )
        print(
            "Please inspect them carefully before applying the actual "
            "configuration (option 3)!"
        )

    nodes = acfg.get_nodes()
    for i in nodes.items():
        node = i[1]

        if (os.path.isfile(rootdir + VPP_STARTUP_FILE) is not True) and (
            os.path.isfile(VPP_REAL_STARTUP_FILE) is True
        ):
            autoconfig_cp(
                node, VPP_REAL_STARTUP_FILE, "{}".format(rootdir + VPP_STARTUP_FILE)
            )
        if (os.path.isfile(rootdir + VPP_HUGE_PAGE_FILE) is not True) and (
            os.path.isfile(VPP_REAL_HUGE_PAGE_FILE) is True
        ):
            autoconfig_cp(
                node, VPP_REAL_HUGE_PAGE_FILE, "{}".format(rootdir + VPP_HUGE_PAGE_FILE)
            )
        if (os.path.isfile(rootdir + VPP_GRUB_FILE) is not True) and (
            os.path.isfile(VPP_REAL_GRUB_FILE) is True
        ):
            autoconfig_cp(
                node, VPP_REAL_GRUB_FILE, "{}".format(rootdir + VPP_GRUB_FILE)
            )

        # Be sure the uio_pci_generic driver is installed
        cmd = "modprobe uio_pci_generic"
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            logging.warning("{} failed on node {} {}".format(cmd, node["host"], stderr))


# noinspection PyUnresolvedReferences
def execute_with_args(args):
    """
    Execute the configuration utility with agruments.

    :param args: The Command line arguments
    :type args: tuple
    """

    # Setup
    autoconfig_setup(ask_questions=False)

    # Execute the command
    if args.show:
        autoconfig_show_system()
    elif args.dry_run:
        autoconfig_dryrun(ask_questions=False)
    elif args.apply:
        autoconfig_apply(ask_questions=False)
    else:
        autoconfig_not_implemented()


def config_main():
    """
    The vpp configuration utility main entry point.

    """

    # Check for root
    if not os.geteuid() == 0:
        sys.exit("\nPlease run the VPP Configuration Utility as root.")

    if len(sys.argv) > 1 and ((sys.argv[1] == "-d") or (sys.argv[1] == "--debug")):
        logging.basicConfig(level=logging.DEBUG)
    else:
        logging.basicConfig(level=logging.ERROR)

    # If no arguments were entered, ask the user questions to
    # get the main parameters
    if len(sys.argv) == 1:
        autoconfig_main()
        return
    elif len(sys.argv) == 2 and ((sys.argv[1] == "-d") or (sys.argv[1] == "--debug")):
        autoconfig_main()
        return

    # There were arguments specified, so execute the utility using
    # command line arguments
    description = "The VPP configuration utility allows the user to "
    "configure VPP in a simple and safe manner. The utility takes input "
    "from the user or the specified .yaml file. The user should then "
    "examine these files to be sure they are correct and then actually "
    "apply the configuration. When run without arguments the utility run "
    "in an interactive mode"

    main_parser = argparse.ArgumentParser(
        prog="arg-test",
        description=description,
        epilog='See "%(prog)s help COMMAND" for help on a specific command.',
    )
    main_parser.add_argument(
        "--apply", "-a", action="store_true", help="Apply the cofiguration."
    )
    main_parser.add_argument(
        "--dry-run",
        "-dr",
        action="store_true",
        help="Create the dryrun configuration files.",
    )
    main_parser.add_argument(
        "--show", "-s", action="store_true", help="Shows basic system information"
    )
    main_parser.add_argument(
        "--debug", "-d", action="count", help="Print debug output (multiple levels)"
    )

    args = main_parser.parse_args()

    return execute_with_args(args)


if __name__ == "__main__":
    config_main()
