#!/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()
