#!/usr/bin/env python3
# -*- coding:utf-8 -*-

try:
    import sys
    import importlib

    importlib.reload(sys)
    import os
    from gspylib.inspection.common import SharedFuncs
    from gspylib.inspection.common.CheckItem import BaseItem
    from gspylib.inspection.common.CheckResult import ResultStatus
    from gspylib.os.gsfile import g_file
    from gspylib.common.VersionInfo import VersionInfo
except ImportError as ie:
    raise Exception("[GAUSS-52200] : Unable to import module: %s." % str(ie))

g_envProfileDist = {}


class CheckEnvProfile(BaseItem):
    def __init__(self):
        super(CheckEnvProfile, self).__init__(self.__class__.__name__)

    def getProcessEnv(self, ProcessNum, Process):
        abnormal_flag = False
        processEnvDist = {}
        # Get environment variables
        if os.path.isfile("/proc/%s/environ" % ProcessNum):
            envInfoList = g_file.readFile("/proc/%s/environ" % ProcessNum)[0].split('\0')
            for env in envInfoList:
                envName = env.split('=')[0].strip()
                processEnvDist[envName] = env.split('=')[-1].strip()
            for env in g_envProfileDist.keys():
                # environment variables if exist
                if env not in processEnvDist.keys() or not processEnvDist[env]:
                    abnormal_flag = True
                    self.result.val += "There is no env[%s] in process %s[%s].\n " % (env, Process, ProcessNum)
                    continue
                # environment variables is GAUSSHOME
                if env == "GAUSSHOME":
                    if g_envProfileDist[env] != processEnvDist[env]:
                        abnormal_flag = True
                        self.result.val += "The env[GAUSSHOME] is inconsistent in process %s[%s] and system.\n" \
                                           "Process: %s\n" % (Process, ProcessNum, processEnvDist[env])
                # environment variables is PATH
                elif env == "PATH":
                    binPath = "%s/bin" % g_envProfileDist["GAUSSHOME"]
                    ProcessEnvList = processEnvDist[env].split(':')
                    if binPath not in ProcessEnvList:
                        abnormal_flag = True
                        self.result.val += "There is no [%s] in process %s[%s]'s environment variable [%s].\n " % (
                            binPath, Process, ProcessNum, env)

        return abnormal_flag

    def doCheck(self):
        g_envProfileDist["GAUSSHOME"] = os.getenv("GAUSSHOME")
        g_envProfileDist["PATH"] = os.getenv("PATH")
        g_envProfileDist["LD_LIBRARY_PATH"] = os.getenv("LD_LIBRARY_PATH")

        self.result.val = ""
        ProcessDisk = {}
        abnormal_flag = False
        if g_envProfileDist["GAUSSHOME"] == "":
            abnormal_flag = True
            self.result.val += "The environmental variable GAUSSHOME is empty.\n"
        else:
            self.result.val += "GAUSSHOME        %s\n" % g_envProfileDist["GAUSSHOME"]

        libPath = "%s/lib" % g_envProfileDist["GAUSSHOME"]
        self.result.val += "LD_LIBRARY_PATH  %s\n" % libPath

        binPath = "%s/bin" % g_envProfileDist["GAUSSHOME"]
        # Whether the environment variable bin is in path
        if binPath not in g_envProfileDist["PATH"].split(':'):
            abnormal_flag = True
            self.result.val += VersionInfo.PRODUCT_NAME + " bin path does not exist in PATH.\n"
        else:
            self.result.val += "PATH             %s\n" % binPath

        if abnormal_flag:
            self.result.rst = ResultStatus.NG
            return

        # Gets the current node information
        ProcessList = self.get_current_node_information()

        # Query process
        for Process in ProcessList:
            cmd = "ps ux | grep '%s/bin/%s' | grep -v 'grep' | awk '{print $2}'" % (self.cluster.appPath, Process)
            output = SharedFuncs.runShellCmd(cmd, self.user, self.mpprcFile)
            if output != "":
                if len(output.split('\n')) > 1:
                    for ProcessNum in output.split('\n'):
                        ProcessDisk[ProcessNum] = [Process]
                else:
                    ProcessDisk[output] = [Process]
            else:
                self.result.val += "The process %s is not exist.\n" % Process
                abnormal_flag = True
        for ProcessNum in ProcessDisk.keys():
            # Get the process environment variables
            result = self.getProcessEnv(ProcessNum, ProcessDisk[ProcessNum])
            if not abnormal_flag:
                abnormal_flag = result

        if abnormal_flag:
            self.result.rst = ResultStatus.NG
        else:
            self.result.rst = ResultStatus.OK

    def get_current_node_information(self):
        """
        function: gets the current node information
        input: NA
        output: NA
        """
        process_list = list()
        nodeInfo = self.cluster.getDbNodeByName(self.host)
        # Check the cm_server process
        if len(nodeInfo.cmservers) > 0:
            process_list.append("cm_server")
        # Check the cm_agent process
        if len(nodeInfo.cmagents) > 0:
            process_list.append("cm_agent")
        # Check the gtm process
        if len(nodeInfo.gtms) > 0:
            process_list.append("gs_gtm")
        # check the number of instances
        if (len(nodeInfo.coordinators) + len(nodeInfo.datanodes)) > 0:
            process_list.append("gaussdb")
        return process_list
