# Copyright 2016 Vmware, Inc. All rights reserved. -- VMware Confidential
# This is a utility class that provides the ability to manipulate rpms
# installed on a linux machine.
#

import logging

from transport import executeCommand
from transport.local import LocalOperationsManager

logger = logging.getLogger(__name__)

localOpsManager = LocalOperationsManager()

def isRpmInstalled(rpmName):
    '''
    Check if rpm is installed on the system or not

    @param rpmName: The rpm name
    @type: str

    '''
    if not rpmName:
        return False

    result = executeCommand(localOpsManager, ['rpm', '-q', rpmName])
    return result.exitCode == 0

def installRpms(rpmList, forced=False, test=False):
    '''
    Installs the list of rpms on the Linux system. If any errors happen none
    rpms will be installed

    @param rpmList: List of rpm names to be installed, full path to them and
      .rpm ext is needed.
    @type rpmList: list

    @param forced: see rpm -- force. Ignores conflicts.
    @type forced: bool

    @param test: see rpm --test. Just report if it will be succsess or not. Does
      not install
    @type test: bool

    @return: True if it was successful, False otherwise
    '''
    logger.info('Installing %s rpms on the system.', len(rpmList))

    if not rpmList:
        return True

    command = ['rpm', '-Uhv']

    if forced:
        command.append('--force')
    if test:
        command.append('--test')

    command += rpmList

    result = executeCommand(localOpsManager, command)
    success = result.exitCode == 0
    logger.info('Rpm installation was %s,exitCode %s, stdout %s, stderr %s', \
                'successful' if success else 'not successful', \
                result.exitCode, result.stdout, result.stderr)
    return success

def removeRpms(rpmList):
    '''
    Removes the list of rpms from the Linux system. If there are install rpms that depend
    on any of those rpms and won't be removed the whole process is aborted and no
    rpms are removed.

    @param rpmList: List of rpm names to be removed. If a rpm is not installed
    it will be ignored
    @type rpmList: list

    @return: None if it was successful, list of rpms that cannot be removed
    '''
    logger.info('Removing %s rpms from the system.', len(rpmList))

    if not rpmList:
        return None
    rpmList = [ rpm for rpm in rpmList if isRpmInstalled(rpm)]

    command = ['rpm', '-e'] + rpmList

    result = executeCommand(localOpsManager, command)
    success = result.exitCode == 0
    logger.info('Rpm removal was %s, stdout %s, stderr %s', 'successful' if success else 'not successful', result.stdout, result.stderr)
    return None if success else rpmList

def validateRpmsRemoval(rpmList):
    '''
    Validates if list of rpms can be removed from the Linux system.

    @param rpmList: List of rpm names to be validate. If a rpm is not installed
    it will be ignored
    @type rpmList: list

    @return: True if it can, False if it cannot due to dependency issues
    '''
    logger.info('Validating if %s rpms can be removed from the system.', rpmList)
    if not rpmList:
        return True
    rpmList = [ rpm for rpm in rpmList if isRpmInstalled(rpm)]

    command = ['rpm', '-e', '--test'] + rpmList

    result = executeCommand(localOpsManager, command)
    success = result.exitCode == 0 and not result.stderr
    logger.info('Rpm removal will be %s, stdout %s, stderr %s', 'successful' if success else 'not successful', result.stdout, result.stderr)
    return success
