#!/usr/bin/python3
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you 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.

import subprocess

depLibraries = ['bzip2', 'gzip', 'unzip', 'openssh-clients', 'nfs-utils', 'wget', 'ws-commons-util', 'commons-dbcp',
                'commons-collections', 'commons-httpclient', 'jpackage-utils', 'mysql-connector-python3', 'python-paramiko', 'ipmitool', 'commons-httpclient', 'commons-collections',
                'commons-pool', 'commons-dbcp', 'jakarta-commons-logging', 'java-*-openjdk']

def runCmd(cmds):
    process = subprocess.Popen(' '.join(cmds), shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
    stdout, stderr = process.communicate()
    if process.returncode != 0:
        raise Exception(stderr.decode('utf-8'))
    return stdout.decode('utf-8')


def getDependentLibraryInfo():
    def getVersion(res, pkgname):
        start = False
        for l in res.split('\n'):
            if "Installed Packages" in l:
                start = True
                continue
            if not start: continue
            
            (key, value) = l.split(':', 2)
            key = key.strip()
            value = value.strip()
            if key == 'Name' and "*" not in pkgname and pkgname not in value:
                print("Required package name %s doesn't equal to package %s installed"%(pkgname, value))
                return 'UNKNOWN'
            if 'Version' in key: return value
            if 'Description' in key: return 'UNKNOWN' # we hit the end
        return 'UNKNOWN'

    libraryMap = {}
    for l in depLibraries:
        cmd = ['yum', 'info', '"%s"'%l]
        try:
            result = runCmd(cmd)
            version = getVersion(result, l)
            libraryMap[l] = version
        except Exception as e:
            print("When finding %s, encounters %s"%(l, e))
            continue
    return libraryMap

def arrangeOutPut(libraryMap):
    msg = ['\n\n\nBelow is the checking list of library version that CloudStack depends on:']
    for l in depLibraries:
        if l in libraryMap:
            entry = "%-40s:    %s"%(l, libraryMap[l])
        else:
            entry = "%-40s:    %s"%(l, 'UNKNOWN')
        msg.append(entry)
    print('\n'.join(msg))
        
if __name__ == '__main__':
    pythonDepLibraries = ['python', 'python3']
    relver = runCmd(['rpm', '-q', 'centos-release'])
    if relver.startswith('centos-release-') and int(relver[len('centos-release-')]) >= 8:
        pythonDepLibraries = ['python2', 'python36']
    depLibraries = pythonDepLibraries + depLibraries

    arrangeOutPut(getDependentLibraryInfo())
