#!/usr/bin/env python3
# -*- coding:utf-8 -*-
try:
    import sys
    import importlib

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


def extractStructure(output):
    result = []
    for line in output.splitlines():
        if (line.find('-') < 0):
            continue
        idx = line.find(':') if line.find(':') > 0 else line.find('(')
        if idx > 0:
            line = line[:idx]
        result.append(repr(line))
    return "\n".join(result)


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

    def doCheck(self):
        self.result.raw = ""
        self.result.val = ""

        cgroupFile = "Gaussdb:%s/Class/" % self.user
        cgroupPath1 = os.path.join("/sys/fs/cgroup/cpu", cgroupFile)
        cgroupPath2 = os.path.join("/dev/cgroup/cpu", cgroupFile)

        if (not os.path.exists(cgroupPath1) and not os.path.exists(cgroupPath2)):
            self.result.rst = ResultStatus.NG
            self.result.val += "The %s not exist nether /sys/fs/cgroup/cpu or /dev/cgroup/cpu\n" % cgroupFile
            return

        cmd = "gs_cgroup -P"
        output = SharedFuncs.runShellCmd(cmd, self.user, self.mpprcFile)
        cgroupStructureParam = extractStructure(output)
        self.result.raw += "The result of '%s':%s\n" % (cmd, cgroupStructureParam)
        self.result.val += "\n".join(['[' + cmd + ']', cgroupStructureParam])
        self.result.val += "\n"
        cmd = "gs_cgroup -p"
        cgroupParam = SharedFuncs.runShellCmd(cmd, self.user, self.mpprcFile)
        self.result.raw += "The result of '%s':%s\n" % (cmd, cgroupParam)
        self.result.val += "\n".join(['[' + cmd + ']', cgroupParam])

        self.result.rst = ResultStatus.OK

    def doSet(self):
        resultStr = ""
        flag = 1
        pids = []
        cmd = "echo $GAUSSHOME "
        gaussAppPath = SharedFuncs.runShellCmd(cmd, self.user, self.mpprcFile)
        mountPath = "/sys/fs/cgroup/"
        cmd = "%s/bin/gs_cgroup -d -U %s" % (gaussAppPath, self.user)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            resultStr += "Failed to use gs_cgroup tool.\n Error : %s" % output
        cmd = "umount /dev/cgroup/"
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            resultStr += "Warning : %s" % output
            cmd = "umount /sys/fs/cgroup/"
            (status, output) = subprocess.getstatusoutput(cmd)
            if (status != 0):
                resultStr += "Warning: %s" % output
                flag = 0
        if (flag == 0):
            cmd = "lsof | grep cgroup"
            (status, output) = subprocess.getstatusoutput(cmd)
            if (status != 0):
                resultStr += "No process related to cgroups."
            else:
                for process in output.splitlines():
                    pids.append(process.split()[1])
                for pid in tuple(pids):
                    cmd = "kill -9 %s" % pid
                    (status, output) = subprocess.getstatusoutput(cmd)
                    if (status != 0):
                        resultStr += "Failed to kill cgroup."
        time.sleep(10)
        cmd = "%s/bin/gs_cgroup -U %s --upgrade -c -H %s -D %s" % \
              (gaussAppPath, self.user, gaussAppPath, mountPath)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            resultStr += "Failed to call cgroup.\n Error : %s" % output
        if (len(resultStr) > 0):
            self.result.val = resultStr
        else:
            self.result.val = "Set Cgroup successfully."
