# Copyright (c) 2016 Cisco 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 __future__ import print_function

"""VPP util library"""
import logging
import re
import subprocess
import requests

from collections import Counter

import distro

ubuntu_pkgs = {'release': ['vpp', 'vpp-plugin-core', 'vpp-plugin-dpdk', 'vpp-api-python', 'python3-vpp-api',
                           'vpp-dbg', 'vpp-dev'],
               'master': ['vpp', 'vpp-plugin-core', 'vpp-plugin-dpdk', 'vpp-api-python', 'python3-vpp-api',
                          'vpp-dbg', 'vpp-dev']}

centos_pkgs = {'release': ['vpp', 'vpp-selinux-policy', 'vpp-plugins', 'vpp-api-lua',
                           'vpp-api-python', 'vpp-debuginfo', 'vpp-devel', 'libvpp0'],
               'master': ['vpp', 'vpp-selinux-policy', 'vpp-plugins', 'vpp-api-lua',
                          'vpp-api-python', 'vpp-debuginfo', 'vpp-devel', 'libvpp0']}


class VPPUtil(object):
    """General class for any VPP related methods/functions."""

    @staticmethod
    def exec_command(cmd, timeout=None):
        """Execute a command on the local node.

        :param cmd: Command to run locally.
        :param timeout: Timeout value
        :type cmd: str
        :type timeout: int
        :return return_code, stdout, stderr
        :rtype: tuple(int, str, str)
        """

        logging.info(" Local Command: {}".format(cmd))
        out = ''
        err = ''
        prc = subprocess.Popen(cmd, shell=True, bufsize=1,
                               stdin=subprocess.PIPE,
                               stdout=subprocess.PIPE,
                               stderr=subprocess.PIPE)

        with prc.stdout:
            lines = prc.stdout.readlines()
            for line in lines:
                if type(line) != str:
                    line = line.decode()
                logging.info("  {}".format(line.strip('\n')))
                out += line

        with prc.stderr:
            lines = prc.stderr.readlines()
            for line in lines:
                if type(line) != str:
                    line = line.decode()
                logging.warning("  {}".format(line.strip('\n')))
                err += line

        ret = prc.wait()

        return ret, out, err

    def _autoconfig_backup_file(self, filename):
        """
        Create a backup file.

        :param filename: The file to backup
        :type filename: str
        """

        # Does a copy of the file exist, if not create one
        ofile = filename + '.orig'
        (ret, stdout, stderr) = self.exec_command('ls {}'.format(ofile))
        if ret != 0:
            logging.debug(stderr)
            if stdout.strip('\n') != ofile:
                cmd = 'sudo cp {} {}'.format(filename, ofile)
                (ret, stdout, stderr) = self.exec_command(cmd)
                if ret != 0:
                    logging.debug(stderr)

    def _install_vpp_ubuntu(self, node, branch, ubuntu_version='xenial'):
        """
        Install the VPP packages

        :param node: Node dictionary with cpuinfo.
        :param branch: VPP branch
        :param ubuntu_version: Ubuntu Version
        :type node: dict
        :type branch: string
        :type ubuntu_version: string
        """

        # Modify the sources list
        sfile = '/etc/apt/sources.list.d/99fd.io.list'

        # Backup the sources list
        self._autoconfig_backup_file(sfile)

        reps = 'deb [trusted=yes] https://packagecloud.io/fdio/'
        reps += '{}/ubuntu {} main\n'.format(branch, ubuntu_version)

        with open(sfile, 'w') as sfd:
            sfd.write(reps)
            sfd.close()

        # Add the key

        key = requests.get(
            'https://packagecloud.io/fdio/{}/gpgkey'.format(branch))
        cmd = 'echo "{}" | apt-key add -'.format(key.content.decode(key.encoding))
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {}'.format(
                cmd,
                node['host'],
                stderr))

        # Install the package
        cmd = 'apt-get -y update'
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} apt-get update failed on node {} {}'.format(
                cmd,
                node['host'],
                stderr))

        # Get the package list
        pkgstr = ''
        for ps in ubuntu_pkgs[branch]:
            pkgstr += ps + ' '

        cmd = 'apt-get -y install {}'.format(pkgstr)
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.format(
                cmd, node['host'], stdout, stderr))

    def _install_vpp_centos(self, node, branch):
        """
        Install the VPP packages

        :param node: Node dictionary with cpuinfo.
        :param branch: The branch name  release or master
        :type node: dict
        :type branch: string
        """

        # Be sure the correct system packages are installed
        cmd = 'yum -y update'
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            logging.debug('{} failed on node {} {}'.format(
                cmd,
                node['host'],
                stderr))

        cmd = 'yum -y install pygpgme yum-utils'
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            logging.debug('{} failed on node {} {}'.format(
                cmd,
                node['host'],
                stderr))

        # Modify the sources list
        sfile = '/etc/yum.repos.d/fdio-release.repo'

        # Backup the sources list
        self._autoconfig_backup_file(sfile)

        # Remove the current file
        cmd = 'rm {}'.format(sfile)
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            logging.debug('{} failed on node {} {}'.format(
                cmd,
                node['host'],
                stderr))

        # Get the file contents

        reps = '\n'.join([
            '[fdio_{}]'.format(branch),
            'name=fdio_{}'.format(branch),
            'baseurl=https://packagecloud.io/fdio/{}/el/7/$basearch'.format(
                branch),
            'repo_gpgcheck=1',
            'gpgcheck=0',
            'enabled=1',
            'gpgkey=https://packagecloud.io/fdio/{}/gpgkey'.format(branch),
            'sslverify=1',
            'sslcacert=/etc/pki/tls/certs/ca-bundle.crt',
            'metadata_expire=300\n',
            '[fdio_{}-source]'.format(branch),
            'name=fdio_release-{}'.format(branch),
            'baseurl=https://packagecloud.io/fdio/{}/el/7/SRPMS'.format(
                branch),
            'repo_gpgcheck=1',
            'gpgcheck=0',
            'enabled=1',
            'gpgkey=https://packagecloud.io/fdio/{}/gpgkey'.format(branch),
            'sslverify =1',
            'sslcacert=/etc/pki/tls/certs/ca-bundle.crt',
            'metadata_expire=300\n'
        ])
        with open(sfile, 'w') as sfd:
            sfd.write(reps)
            sfd.close()

        # Update the fdio repo
        cmd = 'yum clean all'
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            logging.debug('{} failed on node {} {}'.format(
                cmd,
                node['host'],
                stderr))

        cmd = "yum -q makecache -y --disablerepo='*' " \
              "--enablerepo='fdio_{}'".format(branch)
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            logging.debug('{} failed on node {} {}'.format(
                cmd,
                node['host'],
                stderr))

        # Get the package list
        pkgstr = ''
        for ps in centos_pkgs[branch]:
            pkgstr += ps + ' '

        cmd = 'yum -y install {}'.format(pkgstr)
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.format(
                cmd, node['host'], stdout, stderr))

    def install_vpp(self, node, branch):
        """
        Install the VPP packages

        :param node: Node dictionary with cpuinfo.
        :param branch: The branch name
        :type node: dict
        :type branch: string

        """
        distro = self.get_linux_distro()
        logging.info("  {}".format(distro[0]))
        if distro[0] == 'Ubuntu':
            logging.info("Install Ubuntu")
            self._install_vpp_ubuntu(node, branch, ubuntu_version=distro[2])
        elif distro[0] == 'CentOS Linux':
            logging.info("Install CentOS")
            self._install_vpp_centos(node, branch)
        else:
            logging.info("Install CentOS (default)")
            self._install_vpp_centos(node, branch)
        return

    def _uninstall_vpp_ubuntu(self, node):
        """
        Uninstall the VPP packages

        :param node: Node dictionary with cpuinfo.
        :type node: dict
        """

        # get the package list
        pkgstr = ''
        pkgs = self.get_installed_vpp_pkgs()
        for pkg in pkgs:
            pkgname = pkg['name']
            pkgstr += pkgname + ' '

        cmd = 'dpkg --purge {}'.format(pkgstr)
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.format(
                cmd, node['host'], stdout, stderr))

    def _uninstall_vpp_centos(self, node):
        """
        Uninstall the VPP packages

        :param node: Node dictionary with cpuinfo.
        :type node: dict
        """

        pkgstr = ''
        pkgs = self.get_installed_vpp_pkgs()
        for pkg in pkgs:
            pkgname = pkg['name']
            pkgstr += pkgname + ' '

        logging.info("Uninstalling {}".format(pkgstr))
        cmd = 'yum -y remove {}'.format(pkgstr)
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.format(
                cmd, node['host'], stdout, stderr))

    def uninstall_vpp(self, node):
        """
        Uninstall the VPP packages

        :param node: Node dictionary with cpuinfo.
        :type node: dict
        """

        # First stop VPP
        self.stop(node)
        distro = self.get_linux_distro()
        if distro[0] == 'Ubuntu':
            logging.info("Uninstall Ubuntu")
            self._uninstall_vpp_ubuntu(node)
        elif distro[0] == 'CentOS Linux':
            logging.info("Uninstall CentOS")
            self._uninstall_vpp_centos(node)
        else:
            logging.info("Uninstall CentOS (Default)")
            self._uninstall_vpp_centos(node)
            return

    def show_vpp_settings(self, *additional_cmds):
        """
        Print default VPP settings. In case others are needed, can be
        accepted as next parameters (each setting one parameter), preferably
        in form of a string.

        :param additional_cmds: Additional commands that the vpp should print
        settings for.
        :type additional_cmds: tuple
        """
        def_setting_tb_displayed = {
            'IPv6 FIB': 'ip6 fib',
            'IPv4 FIB': 'ip fib',
            'Interface IP': 'int addr',
            'Interfaces': 'int',
            'ARP': 'ip arp',
            'Errors': 'err'
        }

        if additional_cmds:
            for cmd in additional_cmds:
                def_setting_tb_displayed['Custom Setting: {}'.format(cmd)] \
                    = cmd

                for _, value in def_setting_tb_displayed.items():
                    self.exec_command('vppctl sh {}'.format(value))

    @staticmethod
    def get_vms(node):
        """
        Get a list of VMs that are connected to VPP interfaces

        :param node: VPP node.
        :type node: dict
        :returns: Dictionary containing a list of VMs and the interfaces
                  that are connected to VPP
        :rtype: dictionary
        """

        vmdict = {}

        print("Need to implement get vms")

        return vmdict

    @staticmethod
    def get_int_ip(node):
        """
        Get the VPP interfaces and IP addresses

        :param node: VPP node.
        :type node: dict
        :returns: Dictionary containing VPP interfaces and IP addresses
        :rtype: dictionary
        """
        interfaces = {}
        cmd = 'vppctl show int addr'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            return interfaces

        lines = stdout.split('\n')
        if len(lines[0]) != 0:
            if lines[0].split(' ')[0] == 'FileNotFoundError':
                return interfaces

        name = ''
        for line in lines:
            if len(line) == 0:
                continue

            # If the first character is not whitespace
            # create a new interface
            if len(re.findall(r'\s', line[0])) == 0:
                spl = line.split()
                name = spl[0]
                if name == 'local0':
                    continue
                interfaces[name] = {}
                interfaces[name]['state'] = spl[1].lstrip('(').rstrip('):\r')
            else:
                interfaces[name]['address'] = line.lstrip(' ').rstrip('\r')

        return interfaces

    @staticmethod
    def get_hardware(node):
        """
        Get the VPP hardware information and return it in a
        dictionary

        :param node: VPP node.
        :type node: dict
        :returns: Dictionary containing VPP hardware information
        :rtype: dictionary
        """

        interfaces = {}
        cmd = 'vppctl show hard'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            return interfaces

        lines = stdout.split('\n')
        if len(lines[0]) != 0:
            if lines[0].split(' ')[0] == 'FileNotFoundError':
                return interfaces

        for line in lines:
            if len(line) == 0:
                continue

            # If the first character is not whitespace
            # create a new interface
            if len(re.findall(r'\s', line[0])) == 0:
                spl = line.split()
                name = spl[0]
                interfaces[name] = {}
                interfaces[name]['index'] = spl[1]
                interfaces[name]['state'] = spl[2]

            # Ethernet address
            rfall = re.findall(r'Ethernet address', line)
            if rfall:
                spl = line.split()
                interfaces[name]['mac'] = spl[2]

            # Carrier
            rfall = re.findall(r'carrier', line)
            if rfall:
                spl = line.split('carrier ')
                interfaces[name]['carrier'] = spl[1]

            # Socket
            spl = ''
            rfall = re.findall(r'numa \d+', line)
            if rfall:
                spl = rfall[0].split()
                interfaces[name]['numa'] = rfall[0].split()[1]

            # Queues and Descriptors
            rfall = re.findall(r'rx\: queues \d+', line)
            if rfall:
                interfaces[name]['rx queues'] = rfall[0].split()[2]
                rdesc = re.findall(r'desc \d+', line)
                if rdesc:
                    interfaces[name]['rx descs'] = rdesc[0].split()[1]

            rfall = re.findall(r'tx\: queues \d+', line)
            if rfall:
                interfaces[name]['tx queues'] = rfall[0].split()[2]
                rdesc = re.findall(r'desc \d+', line)
                if rdesc:
                    interfaces[name]['tx descs'] = rdesc[0].split()[1]

        return interfaces

    def _get_installed_vpp_pkgs_ubuntu(self):
        """
        Get the VPP hardware information and return it in a
        dictionary

        :returns: List of the packages installed
        :rtype: list
        """

        pkgs = []
        cmd = 'dpkg -l | grep vpp'
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            return pkgs

        lines = stdout.split('\n')
        for line in lines:
            items = line.split()
            if len(items) < 2:
                continue
            pkg = {'name': items[1], 'version': items[2]}
            pkgs.append(pkg)

        return pkgs

    def _get_installed_vpp_pkgs_centos(self):
        """
        Get the VPP hardware information and return it in a
        dictionary

        :returns: List of the packages installed
        :rtype: list
        """

        pkgs = []
        cmd = 'rpm -qa | grep vpp'
        (ret, stdout, stderr) = self.exec_command(cmd)
        if ret != 0:
            return pkgs

        lines = stdout.split('\n')
        for line in lines:
            if len(line) == 0:
                continue

            items = line.split()
            if len(items) < 2:
                pkg = {'name': items[0]}
            else:
                pkg = {'name': items[1], 'version': items[2]}

            pkgs.append(pkg)

        return pkgs

    def get_installed_vpp_pkgs(self):
        """
        Get the VPP hardware information and return it in a
        dictionary

        :returns: List of the packages installed
        :rtype: list
        """

        distro = self.get_linux_distro()
        if distro[0] == 'Ubuntu':
            pkgs = self._get_installed_vpp_pkgs_ubuntu()
        elif distro[0] == 'CentOS Linux':
            pkgs = self._get_installed_vpp_pkgs_centos()
        else:
            pkgs = self._get_installed_vpp_pkgs_centos()
            return []

        return pkgs

    @staticmethod
    def get_interfaces_numa_node(node, *iface_keys):
        """Get numa node on which are located most of the interfaces.

        Return numa node with highest count of interfaces provided as
        arguments.
        Return 0 if the interface does not have numa_node information
        available.
        If all interfaces have unknown location (-1), then return 0.
        If most of interfaces have unknown location (-1), but there are
        some interfaces with known location, then return the second most
        location of the provided interfaces.

        :param node: Node from DICT__nodes.
        :param iface_keys: Interface keys for lookup.
        :type node: dict
        :type iface_keys: strings
        """
        numa_list = []
        for if_key in iface_keys:
            try:
                numa_list.append(node['interfaces'][if_key].get('numa_node'))
            except KeyError:
                pass

        numa_cnt_mc = Counter(numa_list).most_common()
        numa_cnt_mc_len = len(numa_cnt_mc)
        if numa_cnt_mc_len > 0 and numa_cnt_mc[0][0] != -1:
            return numa_cnt_mc[0][0]
        elif numa_cnt_mc_len > 1 and numa_cnt_mc[0][0] == -1:
            return numa_cnt_mc[1][0]

        return 0

    @staticmethod
    def restart(node):
        """

        Starts vpp for a given node

        :param node: VPP node.
        :type node: dict
        """

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

    @staticmethod
    def start(node):
        """

        Starts vpp for a given node

        :param node: VPP node.
        :type node: dict
        """

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

    @staticmethod
    def stop(node):
        """

        Stops vpp for a given node

        :param node: VPP node.
        :type node: dict
        """

        cmd = 'service vpp stop'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            logging.debug('{} failed on node {} {} {}'.
                          format(cmd, node['host'],
                                 stdout, stderr))

    # noinspection RegExpRedundantEscape
    @staticmethod
    def status(node):
        """

        Gets VPP status

        :param: node
        :type node: dict
        :returns: status, errors
        :rtype: tuple(str, list)
        """
        errors = []
        vutil = VPPUtil()
        pkgs = vutil.get_installed_vpp_pkgs()
        if len(pkgs) == 0:
            return "Not Installed", errors

        cmd = 'service vpp status'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)

        # Get the active status
        state = re.findall(r'Active:[\w (\)]+', stdout)[0].split(' ')
        if len(state) > 2:
            statestr = "{} {}".format(state[1], state[2])
        else:
            statestr = "Invalid"

        # For now we won't look for DPDK errors
        # lines = stdout.split('\n')
        # for line in lines:
        #    if 'EAL' in line or \
        #                     'FAILURE' in line or \
        #                     'failed' in line or \
        #                     'Failed' in line:
        #         errors.append(line.lstrip(' '))

        return statestr, errors

    @staticmethod
    def get_linux_distro():
        """
        Get the linux distribution and check if it is supported

        :returns: linux distro, None if the distro is not supported
        :rtype: list
        """

        dist = distro.linux_distribution()
        if dist[0] == 'Ubuntu' or \
                dist[0] == 'CentOS Linux' or \
                dist[:7] == 'Red Hat':
            return dist
        else:
            raise RuntimeError(
                'Linux Distribution {} is not supported'.format(dist[0]))

    @staticmethod
    def version():
        """

        Gets VPP Version information

        :returns: version
        :rtype: dict
        """

        version = {}
        cmd = 'vppctl show version verbose'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            return version

        lines = stdout.split('\n')
        if len(lines[0]) != 0:
            if lines[0].split(' ')[0] == 'FileNotFoundError':
                return version

        for line in lines:
            if len(line) == 0:
                continue
            dct = line.split(':')
            version[dct[0]] = dct[1].lstrip(' ')

        return version

    @staticmethod
    def show_bridge(node):
        """
        Shows the current bridge configuration

        :param node: VPP node.
        :type node: dict
        :returns: A list of interfaces
        """

        ifaces = []
        cmd = 'vppctl show bridge'
        (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
        if ret != 0:
            raise RuntimeError('{} failed on node {} {} {}'.
                               format(cmd, node['host'],
                                      stdout, stderr))
        lines = stdout.split('\r\n')
        bridges = []
        for line in lines:
            if line == 'no bridge-domains in use':
                print(line)
                return ifaces
            if len(line) == 0:
                continue

            lspl = line.lstrip(' ').split()
            if lspl[0] != 'BD-ID':
                bridges.append(lspl[0])

        for bridge in bridges:
            cmd = 'vppctl show bridge {} detail'.format(bridge)
            (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
            if ret != 0:
                raise RuntimeError('{} failed on node {} {} {}'.
                                   format(cmd, node['host'],
                                          stdout, stderr))

        lines = stdout.split('\r\n')
        for line in lines:
            iface = re.findall(r'[a-zA-z]+\d+/\d+/\d+', line)
            if len(iface):
                ifcidx = {'name': iface[0], 'index': line.split()[1]}
                ifaces.append(ifcidx)

        print(stdout)
        return ifaces
