# 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.
from .cloudException import CloudRuntimeException, formatExceptionInfo
import logging
from subprocess import PIPE, Popen
from signal import alarm, signal, SIGALRM, SIGKILL
import sys
import os
class bash:
    def __init__(self, args, timeout=600):
        self.args = args
        logging.debug("execute:%s"%args)
        self.timeout = timeout
        self.process = None
        self.success = False
        self.run()

    def run(self):
        class Alarm(Exception):
            pass
        def alarm_handler(signum, frame):
            raise Alarm

        try:
            self.process = Popen(self.args, shell=True, stdout=PIPE, stderr=PIPE)
            if self.timeout != -1:
                signal(SIGALRM, alarm_handler)
                alarm(self.timeout)

            try:
                self.stdout, self.stderr = self.process.communicate()
                if self.timeout != -1:
                    alarm(0)
            except Alarm:
                os.kill(self.process.pid, SIGKILL)
                raise CloudRuntimeException("Timeout during command execution")

            self.success = self.process.returncode == 0
        except:
            raise CloudRuntimeException(formatExceptionInfo())

        if not self.success:
            logging.debug("Failed to execute:" + self.getErrMsg())

    def isSuccess(self):
        return self.success

    def getStdout(self):
        return self.stdout.decode('utf-8').strip('\n')

    def getLines(self):
        return self.stdout.decode('utf-8').strip('\n')

    def getStderr(self):
        return self.stderr.decode('utf-8').strip('\n')

    def getErrMsg(self):
        if self.isSuccess():
            return ""

        if self.getStderr() is None or self.getStderr() == "":
            return self.getStdout()
        else:
            return self.getStderr()

def initLoging(logFile=None):
    try:
        if logFile is None:
            logging.basicConfig(level=logging.DEBUG)
        else:
            logging.basicConfig(filename=logFile, level=logging.DEBUG)
    except:
        logging.basicConfig(level=logging.DEBUG)

def writeProgressBar(msg, result):
    output = "[%-6s]\n"%"Failed"
    if msg is not None:
        output = "%-30s"%msg
    elif result is True:
        output = "[%-2s]\n"%"OK"
    elif result is False:
        output = "[%-6s]\n"%"Failed"
    sys.stdout.write(output)
    sys.stdout.flush()

class UnknownSystemException(Exception):
    "This Excption is raised if the current operating enviornment is unknown"
    pass

class Distribution:
    def __init__(self):
        self.distro = "Unknown"
        self.release = "Unknown"

        if os.path.exists("/etc/fedora-release"):
            self.distro = "Fedora"
        elif os.path.exists("/etc/redhat-release"):
            version = open("/etc/redhat-release").readline()
            if (version.find("Red Hat Enterprise Linux Server release 6") != -1 or version.find("Scientific Linux release 6") != -1 or
                version.find("CentOS Linux release 6") != -1 or version.find("CentOS release 6.") != -1):
                self.distro = "RHEL6"
            elif (version.find("Red Hat Enterprise Linux Server release 7") != -1 or version.find("Scientific Linux release 7") != -1 or
                version.find("CentOS Linux release 7") != -1 or version.find("CentOS release 7.") != -1):
                self.distro = "RHEL7"
            elif (version.find("Red Hat Enterprise Linux Server release 8") != -1 or version.find("Scientific Linux release 8") != -1 or
                version.find("CentOS Linux release 8") != -1 or version.find("CentOS release 8.") != -1 or
                version.find("Linux release 8") != -1):
                self.distro = "RHEL8"
            elif (version.find("Red Hat Enterprise Linux Server release 9") != -1 or version.find("Scientific Linux release 9") != -1 or
                version.find("Red Hat Enterprise Linux release 9") != -1 or version.find("Linux release 9.") != -1 or
                version.find("Linux release 9") != -1):
                self.distro = "RHEL9"
            elif (version.find("Red Hat Enterprise Linux Server release 10") != -1 or version.find("Scientific Linux release 10") != -1 or
                version.find("Red Hat Enterprise Linux release 10") != -1 or version.find("Linux release 10.") != -1 or
                version.find("Linux release 10") != -1):
                self.distro = "RHEL10"
            elif version.find("CentOS") != -1:
                self.distro = "CentOS"
            else:
                self.distro = "RHEL5"
        elif os.path.exists("/etc/legal") and "Ubuntu" in open("/etc/legal").read(-1):
            self.distro = "Ubuntu"
            kernel = bash("uname -r").getStdout()
            if kernel.find("2.6.32") != -1:
                self.release = "10.04"
            self.arch = bash("uname -m").getStdout()
        elif os.path.exists("/usr/bin/lsb_release"):
            o = bash("/usr/bin/lsb_release -i")
            distributor = o.getStdout().split(":\t")[1]
            if "Debian" in distributor:
                # This obviously needs a rewrite at some point
                self.distro = "Ubuntu"
            else:
                raise UnknownSystemException(distributor)
        elif os.path.exists("/etc/os-release"):
            version = open("/etc/os-release").readline()
            distributor = version.split("=")[1].replace('"', '').strip()
            if "SUSE" in distributor or "SLES" in distributor:
                self.distro = "SUSE"
            else:
                raise UnknownSystemException(distributor)
        else:
            raise UnknownSystemException

    def getVersion(self):
        return self.distro
    def getRelease(self):
        return self.release
    def getArch(self):
        return self.arch


class serviceOps:
    pass
class serviceOpsRedhat(serviceOps):
    def isServiceRunning(self, servicename):
        try:
            o = bash("service " + servicename + " status")
            if "running" in o.getStdout() or "start" in o.getStdout() or "Running" in o.getStdout():
                return True
            else:
                return False
        except:
            return False

    def stopService(self, servicename,force=False):
        if self.isServiceRunning(servicename) or force:
            return bash("service " + servicename +" stop").isSuccess()

        return True
    def disableService(self, servicename):
        result = self.stopService(servicename)
        bash("chkconfig --del " + servicename)
        return result

    def startService(self, servicename,force=False):
        if not self.isServiceRunning(servicename) or force:
            return bash("service " + servicename + " start").isSuccess()
        return True

    def enableService(self, servicename,forcestart=False):
        bash("chkconfig --level 2345 " + servicename + " on")
        return self.startService(servicename,force=forcestart)

    def isKVMEnabled(self):
        if os.path.exists("/dev/kvm"):
            return True
        else:
            return False

class serviceOpsUbuntu(serviceOps):
    def isServiceRunning(self, servicename):
        try:
            o = bash("sudo /usr/sbin/service " + servicename + " status")
            if "not running" in o.getStdout():
                return False
            else:
                return True
        except:
            return False

    def stopService(self, servicename,force=True):
        if self.isServiceRunning(servicename) or force:
            return bash("sudo /usr/sbin/service " + servicename +" stop").isSuccess()

    def disableService(self, servicename):
        result = self.stopService(servicename)
        bash("sudo update-rc.d -f " + servicename + " remove")
        return result

    def startService(self, servicename,force=True):
        if not self.isServiceRunning(servicename) or force:
            return bash("sudo /usr/sbin/service " + servicename + " start").isSuccess()

    def enableService(self, servicename,forcestart=True):
        bash("sudo update-rc.d -f " + servicename + " remove")
        bash("sudo update-rc.d -f " + servicename + " defaults")
        return self.startService(servicename,force=forcestart)

    def isKVMEnabled(self):
        return bash("kvm-ok").isSuccess()

class serviceOpsRedhat7Later(serviceOps):
    def isServiceRunning(self, servicename):
        try:
            o = bash("systemctl is-active " + servicename)
            textout = o.getStdout()
            return "inactive" not in textout and "failed" not in textout
        except:
            return False

    def stopService(self, servicename,force=False):
        if self.isServiceRunning(servicename) or force:
            return bash("systemctl stop " + servicename).isSuccess()

        return True
    def disableService(self, servicename):
        result = self.stopService(servicename)
        bash("systemctl disable " + servicename)
        return result

    def startService(self, servicename,force=False):
        if not self.isServiceRunning(servicename) or force:
            return bash("systemctl start " + servicename).isSuccess()
        return True

    def enableService(self, servicename,forcestart=False):
        bash("systemctl enable " + servicename)
        return self.startService(servicename,force=forcestart)

    def isKVMEnabled(self):
        if os.path.exists("/dev/kvm"):
            return True
        else:
            return False

class serviceOpsSUSE(serviceOpsRedhat7Later):
    pass
