#!/usr/bin/python2
"""
Software package management library.

This is an abstraction layer on top of the existing distributions high level
package managers. It supports package operations useful for testing purposes,
and multiple high level package managers (here called backends). If you want
to make this lib to support your particular package manager/distro, please
implement the given backend class.

@author: Higor Vieira Alves (halves@br.ibm.com)
@author: Lucas Meneghel Rodrigues (lmr@redhat.com)
@author: Ramon de Carvalho Valle (rcvalle@br.ibm.com)

@copyright: IBM 2008-2009
@copyright: Red Hat 2009-2010
"""
import os, re, logging, optparse, random, string
try:
    import yum
except:
    pass
import common

from autotest_lib.client.bin import os_dep, utils
from autotest_lib.client.common_lib import error
from autotest_lib.client.common_lib import logging_config, logging_manager
from autotest_lib.client.common_lib import seven


def generate_random_string(length):
    """
    Return a random string using alphanumeric characters.

    @length: Length of the string that will be generated.
    """
    r = random.SystemRandom()
    str = ""
    chars = string.letters + string.digits
    while length > 0:
        str += r.choice(chars)
        length -= 1
    return str


class SoftwareManagerLoggingConfig(logging_config.LoggingConfig):
    """
    Used with the sole purpose of providing convenient logging setup
    for the KVM test auxiliary programs.
    """
    def configure_logging(self, results_dir=None, verbose=False):
        super(SoftwareManagerLoggingConfig, self).configure_logging(
                                                            use_console=True,
                                                            verbose=verbose)


class SystemInspector(object):
    """
    System inspector class.

    This may grow up to include more complete reports of operating system and
    machine properties.
    """
    def __init__(self):
        """
        Probe system, and save information for future reference.
        """
        self.distro = utils.get_os_vendor()
        self.high_level_pms = ['apt-get', 'yum', 'zypper']


    def get_package_management(self):
        """
        Determine the supported package management systems present on the
        system. If more than one package management system installed, try
        to find the best supported system.
        """
        list_supported = []
        for high_level_pm in self.high_level_pms:
            try:
                os_dep.command(high_level_pm)
                list_supported.append(high_level_pm)
            except:
                pass

        pm_supported = None
        if len(list_supported) == 0:
            pm_supported = None
        if len(list_supported) == 1:
            pm_supported = list_supported[0]
        elif len(list_supported) > 1:
            if 'apt-get' in list_supported and self.distro in ['Debian', 'Ubuntu']:
                pm_supported = 'apt-get'
            elif 'yum' in list_supported and self.distro == 'Fedora':
                pm_supported = 'yum'
            else:
                pm_supported = list_supported[0]

        logging.debug('Package Manager backend: %s' % pm_supported)
        return pm_supported


class SoftwareManager(object):
    """
    Package management abstraction layer.

    It supports a set of common package operations for testing purposes, and it
    uses the concept of a backend, a helper class that implements the set of
    operations of a given package management tool.
    """
    def __init__(self):
        """
        Class constructor.

        Determines the best supported package management system for the given
        operating system running and initializes the appropriate backend.
        """
        inspector = SystemInspector()
        backend_type = inspector.get_package_management()
        if backend_type == 'yum':
            self.backend = YumBackend()
        elif backend_type == 'zypper':
            self.backend = ZypperBackend()
        elif backend_type == 'apt-get':
            self.backend = AptBackend()
        else:
            raise NotImplementedError('Unimplemented package management '
                                      'system: %s.' % backend_type)


    def check_installed(self, name, version=None, arch=None):
        """
        Check whether a package is installed on this system.

        @param name: Package name.
        @param version: Package version.
        @param arch: Package architecture.
        """
        return self.backend.check_installed(name, version, arch)


    def list_all(self):
        """
        List all installed packages.
        """
        return self.backend.list_all()


    def list_files(self, name):
        """
        Get a list of all files installed by package [name].

        @param name: Package name.
        """
        return self.backend.list_files(name)


    def install(self, name):
        """
        Install package [name].

        @param name: Package name.
        """
        return self.backend.install(name)


    def remove(self, name):
        """
        Remove package [name].

        @param name: Package name.
        """
        return self.backend.remove(name)


    def add_repo(self, url):
        """
        Add package repo described by [url].

        @param name: URL of the package repo.
        """
        return self.backend.add_repo(url)


    def remove_repo(self, url):
        """
        Remove package repo described by [url].

        @param url: URL of the package repo.
        """
        return self.backend.remove_repo(url)


    def upgrade(self):
        """
        Upgrade all packages available.
        """
        return self.backend.upgrade()


    def provides(self, file):
        """
        Returns a list of packages that provides a given capability to the
        system (be it a binary, a library).

        @param file: Path to the file.
        """
        return self.backend.provides(file)


    def install_what_provides(self, file):
        """
        Installs package that provides [file].

        @param file: Path to file.
        """
        provides = self.provides(file)
        if provides is not None:
            self.install(provides)
        else:
            logging.warning('No package seems to provide %s', file)


class RpmBackend(object):
    """
    This class implements operations executed with the rpm package manager.

    rpm is a lower level package manager, used by higher level managers such
    as yum and zypper.
    """
    def __init__(self):
        self.lowlevel_base_cmd = os_dep.command('rpm')


    def _check_installed_version(self, name, version):
        """
        Helper for the check_installed public method.

        @param name: Package name.
        @param version: Package version.
        """
        cmd = (self.lowlevel_base_cmd + ' -q --qf %{VERSION} ' + name +
               ' 2> /dev/null')
        inst_version = utils.system_output(cmd)

        if inst_version >= version:
            return True
        else:
            return False


    def check_installed(self, name, version=None, arch=None):
        """
        Check if package [name] is installed.

        @param name: Package name.
        @param version: Package version.
        @param arch: Package architecture.
        """
        if arch:
            cmd = (self.lowlevel_base_cmd + ' -q --qf %{ARCH} ' + name +
                   ' 2> /dev/null')
            inst_archs = utils.system_output(cmd)
            inst_archs = inst_archs.split('\n')

            for inst_arch in inst_archs:
                if inst_arch == arch:
                    return self._check_installed_version(name, version)
            return False

        elif version:
            return self._check_installed_version(name, version)
        else:
            cmd = 'rpm -q ' + name + ' 2> /dev/null'
            return (os.system(cmd) == 0)


    def list_all(self):
        """
        List all installed packages.
        """
        installed_packages = utils.system_output('rpm -qa').splitlines()
        return installed_packages


    def list_files(self, name):
        """
        List files installed on the system by package [name].

        @param name: Package name.
        """
        path = os.path.abspath(name)
        if os.path.isfile(path):
            option = '-qlp'
            name = path
        else:
            option = '-ql'

        l_cmd = 'rpm' + ' ' + option + ' ' + name + ' 2> /dev/null'

        try:
            result = utils.system_output(l_cmd)
            list_files = result.split('\n')
            return list_files
        except error.CmdError:
            return []


class DpkgBackend(object):
    """
    This class implements operations executed with the dpkg package manager.

    dpkg is a lower level package manager, used by higher level managers such
    as apt and aptitude.
    """
    def __init__(self):
        self.lowlevel_base_cmd = os_dep.command('dpkg')


    def check_installed(self, name):
        if os.path.isfile(name):
            n_cmd = (self.lowlevel_base_cmd + ' -f ' + name +
                     ' Package 2>/dev/null')
            name = utils.system_output(n_cmd)
        i_cmd = self.lowlevel_base_cmd + ' -s ' + name + ' 2>/dev/null'
        # Checking if package is installed
        package_status = utils.system_output(i_cmd, ignore_status=True)
        not_inst_pattern = re.compile('not-installed', re.IGNORECASE)
        dpkg_not_installed = re.search(not_inst_pattern, package_status)
        if dpkg_not_installed:
            return False
        return True


    def list_all(self):
        """
        List all packages available in the system.
        """
        installed_packages = []
        raw_list = utils.system_output('dpkg -l').splitlines()[5:]
        for line in raw_list:
            parts = line.split()
            if parts[0] == "ii":  # only grab "installed" packages
                installed_packages.append("%s-%s" % (parts[1], parts[2]))


    def list_files(self, package):
        """
        List files installed by package [package].

        @param package: Package name.
        @return: List of paths installed by package.
        """
        if os.path.isfile(package):
            l_cmd = self.lowlevel_base_cmd + ' -c ' + package
        else:
            l_cmd = self.lowlevel_base_cmd + ' -l ' + package
        return utils.system_output(l_cmd).split('\n')


class YumBackend(RpmBackend):
    """
    Implements the yum backend for software manager.

    Set of operations for the yum package manager, commonly found on Yellow Dog
    Linux and Red Hat based distributions, such as Fedora and Red Hat
    Enterprise Linux.
    """
    def __init__(self):
        """
        Initializes the base command and the yum package repository.
        """
        super(YumBackend, self).__init__()
        executable = os_dep.command('yum')
        base_arguments = '-y'
        self.base_command = executable + ' ' + base_arguments
        self.repo_file_path = '/etc/yum.repos.d/autotest.repo'
        self.cfgparser = seven.config_parser()
        self.cfgparser.read(self.repo_file_path)
        y_cmd = executable + ' --version | head -1'
        self.yum_version = utils.system_output(y_cmd, ignore_status=True)
        logging.debug('Yum backend initialized')
        logging.debug('Yum version: %s' % self.yum_version)
        self.yum_base = yum.YumBase()


    def _cleanup(self):
        """
        Clean up the yum cache so new package information can be downloaded.
        """
        utils.system("yum clean all")


    def install(self, name):
        """
        Installs package [name]. Handles local installs.
        """
        if os.path.isfile(name):
            name = os.path.abspath(name)
            command = 'localinstall'
        else:
            command = 'install'

        i_cmd = self.base_command + ' ' + command + ' ' + name

        try:
            utils.system(i_cmd)
            return True
        except:
            return False


    def remove(self, name):
        """
        Removes package [name].

        @param name: Package name (eg. 'ipython').
        """
        r_cmd = self.base_command + ' ' + 'erase' + ' ' + name
        try:
            utils.system(r_cmd)
            return True
        except:
            return False


    def add_repo(self, url):
        """
        Adds package repository located on [url].

        @param url: Universal Resource Locator of the repository.
        """
        # Check if we URL is already set
        for section in self.cfgparser.sections():
            for option, value in self.cfgparser.items(section):
                if option == 'url' and value == url:
                    return True

        # Didn't find it, let's set it up
        while True:
            section_name = 'software_manager' + '_' + generate_random_string(4)
            if not self.cfgparser.has_section(section_name):
                break
        self.cfgparser.add_section(section_name)
        self.cfgparser.set(section_name, 'name',
                           'Repository added by the autotest software manager.')
        self.cfgparser.set(section_name, 'url', url)
        self.cfgparser.set(section_name, 'enabled', 1)
        self.cfgparser.set(section_name, 'gpgcheck', 0)
        self.cfgparser.write(self.repo_file_path)


    def remove_repo(self, url):
        """
        Removes package repository located on [url].

        @param url: Universal Resource Locator of the repository.
        """
        for section in self.cfgparser.sections():
            for option, value in self.cfgparser.items(section):
                if option == 'url' and value == url:
                    self.cfgparser.remove_section(section)
                    self.cfgparser.write(self.repo_file_path)


    def upgrade(self):
        """
        Upgrade all available packages.
        """
        r_cmd = self.base_command + ' ' + 'update'
        try:
            utils.system(r_cmd)
            return True
        except:
            return False


    def provides(self, name):
        """
        Returns a list of packages that provides a given capability.

        @param name: Capability name (eg, 'foo').
        """
        d_provides = self.yum_base.searchPackageProvides(args=[name])
        provides_list = [key for key in d_provides]
        if provides_list:
            logging.info("Package %s provides %s", provides_list[0], name)
            return str(provides_list[0])
        else:
            return None


class ZypperBackend(RpmBackend):
    """
    Implements the zypper backend for software manager.

    Set of operations for the zypper package manager, found on SUSE Linux.
    """
    def __init__(self):
        """
        Initializes the base command and the yum package repository.
        """
        super(ZypperBackend, self).__init__()
        self.base_command = os_dep.command('zypper') + ' -n'
        z_cmd = self.base_command + ' --version'
        self.zypper_version = utils.system_output(z_cmd, ignore_status=True)
        logging.debug('Zypper backend initialized')
        logging.debug('Zypper version: %s' % self.zypper_version)


    def install(self, name):
        """
        Installs package [name]. Handles local installs.

        @param name: Package Name.
        """
        path = os.path.abspath(name)
        i_cmd = self.base_command + ' install -l ' + name
        try:
            utils.system(i_cmd)
            return True
        except:
            return False


    def add_repo(self, url):
        """
        Adds repository [url].

        @param url: URL for the package repository.
        """
        ar_cmd = self.base_command + ' addrepo ' + url
        try:
            utils.system(ar_cmd)
            return True
        except:
            return False


    def remove_repo(self, url):
        """
        Removes repository [url].

        @param url: URL for the package repository.
        """
        rr_cmd = self.base_command + ' removerepo ' + url
        try:
            utils.system(rr_cmd)
            return True
        except:
            return False


    def remove(self, name):
        """
        Removes package [name].
        """
        r_cmd = self.base_command + ' ' + 'erase' + ' ' + name

        try:
            utils.system(r_cmd)
            return True
        except:
            return False


    def upgrade(self):
        """
        Upgrades all packages of the system.
        """
        u_cmd = self.base_command + ' update -l'

        try:
            utils.system(u_cmd)
            return True
        except:
            return False


    def provides(self, name):
        """
        Searches for what provides a given file.

        @param name: File path.
        """
        p_cmd = self.base_command + ' what-provides ' + name
        list_provides = []
        try:
            p_output = utils.system_output(p_cmd).split('\n')[4:]
            for line in p_output:
                line = [a.strip() for a in line.split('|')]
                try:
                    state, pname, type, version, arch, repository = line
                    if pname not in list_provides:
                        list_provides.append(pname)
                except IndexError:
                    pass
            if len(list_provides) > 1:
                logging.warning('More than one package found, '
                                'opting by the first queue result')
            if list_provides:
                logging.info("Package %s provides %s", list_provides[0], name)
                return list_provides[0]
            return None
        except:
            return None


class AptBackend(DpkgBackend):
    """
    Implements the apt backend for software manager.

    Set of operations for the apt package manager, commonly found on Debian and
    Debian based distributions, such as Ubuntu Linux.
    """
    def __init__(self):
        """
        Initializes the base command and the debian package repository.
        """
        super(AptBackend, self).__init__()
        executable = os_dep.command('apt-get')
        self.base_command = executable + ' -y'
        self.repo_file_path = '/etc/apt/sources.list.d/autotest'
        self.apt_version = utils.system_output('apt-get -v | head -1',
                                               ignore_status=True)
        logging.debug('Apt backend initialized')
        logging.debug('apt version: %s' % self.apt_version)


    def install(self, name):
        """
        Installs package [name].

        @param name: Package name.
        """
        command = 'install'
        i_cmd = self.base_command + ' ' + command + ' ' + name

        try:
            utils.system(i_cmd)
            return True
        except:
            return False


    def remove(self, name):
        """
        Remove package [name].

        @param name: Package name.
        """
        command = 'remove'
        flag = '--purge'
        r_cmd = self.base_command + ' ' + command + ' ' + flag + ' ' + name

        try:
            utils.system(r_cmd)
            return True
        except:
            return False


    def add_repo(self, repo):
        """
        Add an apt repository.

        @param repo: Repository string. Example:
                'deb http://archive.ubuntu.com/ubuntu/ maverick universe'
        """
        repo_file = open(self.repo_file_path, 'a')
        repo_file_contents = repo_file.read()
        if repo not in repo_file_contents:
            repo_file.write(repo)


    def remove_repo(self, repo):
        """
        Remove an apt repository.

        @param repo: Repository string. Example:
                'deb http://archive.ubuntu.com/ubuntu/ maverick universe'
        """
        repo_file = open(self.repo_file_path, 'r')
        new_file_contents = []
        for line in repo_file.readlines:
            if not line == repo:
                new_file_contents.append(line)
        repo_file.close()
        new_file_contents = "\n".join(new_file_contents)
        repo_file.open(self.repo_file_path, 'w')
        repo_file.write(new_file_contents)
        repo_file.close()


    def upgrade(self):
        """
        Upgrade all packages of the system with eventual new versions.
        """
        ud_command = 'update'
        ud_cmd = self.base_command + ' ' + ud_command
        try:
            utils.system(ud_cmd)
        except:
            logging.error("Apt package update failed")
        up_command = 'upgrade'
        up_cmd = self.base_command + ' ' + up_command
        try:
            utils.system(up_cmd)
            return True
        except:
            return False


    def provides(self, file):
        """
        Return a list of packages that provide [file].

        @param file: File path.
        """
        if not self.check_installed('apt-file'):
            self.install('apt-file')
        command = os_dep.command('apt-file')
        cache_update_cmd = command + ' update'
        try:
            utils.system(cache_update_cmd, ignore_status=True)
        except:
            logging.error("Apt file cache update failed")
        fu_cmd = command + ' search ' + file
        try:
            provides = utils.system_output(fu_cmd).split('\n')
            list_provides = []
            for line in provides:
                if line:
                    try:
                        line = line.split(':')
                        package = line[0].strip()
                        path = line[1].strip()
                        if path == file and package not in list_provides:
                            list_provides.append(package)
                    except IndexError:
                        pass
            if len(list_provides) > 1:
                logging.warning('More than one package found, '
                                'opting by the first queue result')
            if list_provides:
                logging.info("Package %s provides %s", list_provides[0], file)
                return list_provides[0]
            return None
        except:
            return None


if __name__ == '__main__':
    parser = optparse.OptionParser(
    "usage: %prog [install|remove|list-all|list-files|add-repo|remove-repo|"
    "upgrade|what-provides|install-what-provides] arguments")
    parser.add_option('--verbose', dest="debug", action='store_true',
                      help='include debug messages in console output')

    options, args = parser.parse_args()
    debug = options.debug
    logging_manager.configure_logging(SoftwareManagerLoggingConfig(),
                                      verbose=debug)
    software_manager = SoftwareManager()
    if args:
        action = args[0]
        args = " ".join(args[1:])
    else:
        action = 'show-help'

    if action == 'install':
        software_manager.install(args)
    elif action == 'remove':
        software_manager.remove(args)
    if action == 'list-all':
        software_manager.list_all()
    elif action == 'list-files':
        software_manager.list_files(args)
    elif action == 'add-repo':
        software_manager.add_repo(args)
    elif action == 'remove-repo':
        software_manager.remove_repo(args)
    elif action == 'upgrade':
        software_manager.upgrade()
    elif action == 'what-provides':
        software_manager.provides(args)
    elif action == 'install-what-provides':
        software_manager.install_what_provides(args)
    elif action == 'show-help':
        parser.print_help()
