#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import stat
import sys
import subprocess
import os
import pwd
import grp
import json
import shutil
import _thread as thread
try:
    sys.path.append(sys.path[0] + "/../../")
    from gspylib.common.ErrorCode import ErrorCode
    from gspylib.os.gsplatform import g_Platform
except Exception as ie:
    sys.exit("[GAUSS-52200] : Unable to import module: %s." % str(ie))


class fileManage():
    """
    Class to handle OS file operations
    """
    SHELL_CMD_DICT = {
        "deleteFile": "(if [ -f '%s' ];then rm -f '%s';fi)",
        "deleteLibFile": "cd %s && ls | grep -E '%s'|xargs rm -f",
        "cleanDir": "(if [ -d '%s' ];then rm -rf '%s'/* && cd '%s' && ls -A | xargs rm -rf ; fi)",
        "execShellFile": "sh %s",
        "deleteDir": "(if [ -d '%s' ];then rm -rf '%s';fi)",
        "deleteLib": "(if [ -e '%s' ];then rm -rf '%s';fi)",
        "grepFile": "if [ -f '%s' ];then grep -Er '\<%s\>' %s;fi",
        "createDir": "(if [ ! -d '%s' ]; then mkdir -p '%s' -m %s;fi)",
        "createFile": "touch '%s' && chmod %s '%s'",
        "deleteBatchFiles": "rm -f %s*",
        "compressTarFile": "cd '%s' && tar -zcf '%s' %s && chmod %s '%s' ",
        "decompressTarFile": "cd '%s' && tar -xf '%s' ",
        "copyFile": " cp -rf %s %s ",
        "sshCmd": "export LD_LIBRARY_PATH=/lib64:$LD_LIBRARY_PATH; ssh %s -n %s 'source %s;%s'",
        "renameFile": "(if [ -f '%s' ];then mv '%s' '%s';fi)",
        "cleanFile": "if [ -f %s ]; then echo '' > %s; fi",
        "exeRemoteShellCMD": "export LD_LIBRARY_PATH=/lib64:$LD_LIBRARY_PATH; ssh %s -n %s 'source %s;%s'",
        "exeRemoteShellCMD1": "export LD_LIBRARY_PATH=/lib64:$LD_LIBRARY_PATH; ssh %s -n %s \"%s\"",
        "userExeRemoteShellCmd": "su - %s -c \"export LD_LIBRARY_PATH=/lib64:$LD_LIBRARY_PATH; ssh %s -n %s '%s'\"",
        "checkUserPermission": "su - %s -c \"cd '%s'\"",
        "getFileTime": "echo $[`date +%%s`-`stat -c %%Y %s`]",
        "scpFileToRemote": "export LD_LIBRARY_PATH=/lib64:$LD_LIBRARY_PATH; scp '%s' '%s':'%s'",
        "scpFileToRemoteIPv6": "export LD_LIBRARY_PATH=/lib64:$LD_LIBRARY_PATH; scp '%s' '[%s]':'%s'",
        "scpFileFromRemote": "export LD_LIBRARY_PATH=/lib64:$LD_LIBRARY_PATH; scp '%s':'%s' '%s'",
        "scpFileFromRemoteIPv6": "export LD_LIBRARY_PATH=/lib64:$LD_LIBRARY_PATH; scp '[%s]':'%s' '%s'",
        "findfiles": "cd %s && find . -type l -print",
        "copyFile1": "(if [ -f '%s' ];then cp '%s' '%s';fi)",
        "copyFile2": "(if [ -f '%s' ] && [ ! -f '%s' ];then cp '%s' '%s';fi)",
        "copyFile3": "(if [ -f '%s' ] && [ ! -f '%s' ];then install -m %s '%s' '%s';fi)",
        "copyRemoteFile": "(if [ -d '%s' ];then export LD_LIBRARY_PATH=/lib64:$LD_LIBRARY_PATH; scp '%s':'%s' '%s';fi)",
        "cleanDir1": "(if [ -d '%s' ]; then cd '%s' && rm -rf '%s' && rm -rf '%s' && cd -; fi)",
        "cleanDir2": "(if [ -d '%s' ]; then rm -rf '%s'/* && cd '%s' && ls -A | xargs rm -rf && cd -; fi)",
        "cleanDir3": "rm -rf '%s'/* && cd '%s' && ls -A | xargs rm -rf && cd - ",
        "cleanDir4": "rm -rf %s/*",
        "checkNodeConnection": "ping %s -i 1 -c 3 |grep ttl |wc -l",
        "checkNodeConnectionIPv6": "ping6 %s -i 1 -c 3 |grep ttl |wc -l",
        "overWriteFile": "echo '%s' > '%s'",
        "physicMemory": "cat /proc/meminfo | grep MemTotal",
        "findFile": "(if [ -d '%s' ]; then find '%s' -type f;fi)",
        "unzipForce": "unzip -o '%s' -d '%s'",
        "killAll": "killall %s",
        "sleep": "sleep %s",
        "softLink": "ln -s '%s' '%s'",
        "findwithcd": "cd %s && find ./ -name %s",
        "installRpm": "rpm -ivh --nofiledigest %s --nodeps --force --prefix=%s",
        "changeMode": "chmod %s %s",
        "checkPassword": "export LC_ALL=C; chage -l %s | grep -i %s",
        "changeModeByType": "find %s -type %s -print0 |xargs -0 chmod %s",
        "compareFile": "sha256sum %s %s",
        "getNetworkCardName":
            "cat /proc/net/dev | awk '{i++; if(i>2){print $1}}' \
            | sed 's/^[\t]*//g' | sed 's/[:]*$//g'",
        "checkIP": "ifconfig %s | grep 'inet[6]*'",
        "check1822Card": "ethtool -i %s|grep 'driver: hinic'|wc -l",
        "checkcpu": "lscpu",
        "getInterrupt":
            "cat /proc/interrupts | grep -E '%s' | awk -F ':' \
            '{print $1}' | sed 's/[[:space:]]//g'",
        "cpuInfo": "cat /proc/cpuinfo |grep 'processor' |wc -l"
    }

    def __init__(self):
        pass

    @staticmethod
    def createFile(path, overwrite=True, mode=None):
        """
        function: create file and set the permission
        input:
            path: the file path.
            overwrite: if file already exists and this parameter is true, we can overwrtie it.
            mode: Specify file permissions, type is int and start with 0. ex: 0700
        output:
            return true or false.
        """
        try:
            if (overwrite):
                cmd = g_Platform.getCreateFileCmd(path)
                if (mode):
                    cmd += "; %s" % g_Platform.getChmodCmd(str(mode), path)
                (status, output) = subprocess.getstatusoutput(cmd)
                if (status != 0):
                    raise Exception(output)
            else:
                # create file by python API
                if (mode):
                    os.mknod(path, mode)
                else:
                    os.mknod(path)
        except Exception as e:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50206"] % path + " Error:\n%s" % str(e))

        return True

    def removeFile(self, path, cmdType="shell"):
        """
        function: remove a file
        input: the path of file(include file name)
        output: return true or false
        """
        if (cmdType == "python"):
            # no file need remove.
            if (not os.path.exists(path)):
                return True
            # check if is a file.
            if (not os.path.isfile(path)):
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50210"] % path)
            try:
                # remove file.
                os.remove(path)
            except Exception:
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50207"] % path)
        else:
            # Support* for fuzzy matching
            if ("*" in path):
                path = self.withAsteriskPath(path)
                cmd = g_Platform.getRemoveCmd('file') + path
            else:
                cmd = g_Platform.getRemoveCmd('file') + "'" + path + "'"
            (status, output) = subprocess.getstatusoutput(cmd)
            if (status != 0):
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50207"] % path + " Error:\n%s" % output)
        return True

    @staticmethod
    def moveFile(src, dest, overwrite=True):
        """
        function: move a file
        input:
            src: the dir of file
            dest: the dir which want to move
        output:
            return true or false
        """
        # check if can overwrite
        if (os.path.exists(dest) and not overwrite):
            raise Exception(ErrorCode.GAUSS_501["GAUSS_50102"] % ("parameter overwrite", dest))
        try:
            if (overwrite):
                cmd = g_Platform.getMoveFileCmd(src, dest)
                (status, output) = subprocess.getstatusoutput(cmd)
                if (status != 0):
                    raise Exception(output)
            else:
                # move file
                shutil.move(src, dest)
        except Exception as e:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50232"] % (src, dest) + " Error:\n%s" % str(e))

        return True

    @staticmethod
    def readFile(filename, keyword="", rows=0, encoding=None):
        """
        function: read the content of a file
        input:
            filename: the name and path of the file
            keyword: read line include keyword
            rows: the row number, which want to read
            offset: keep the parameter, but do nothing
        output:list
        """
        listKey = []
        strRows = ""
        fp = None
        # check if file exists.
        if (not os.path.exists(filename)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % filename)
        try:
            if encoding:
                fp = open(filename, 'r', encoding=encoding)
            else:
                fp = open(filename, 'r')
            allLines = fp.readlines()
            fp.close()
        except Exception:
            if fp:
                fp.close()
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50204"] % filename)
        # get keyword lines
        if (keyword != ""):
            for line in allLines:
                flag = line.find(keyword)
                if (flag >= 0):
                    listKey.append(line)
        # get content of row
        if (rows):
            if (not str(rows).isdigit()):
                raise Exception
            if (rows > 0):
                row_num = rows - 1
            else:
                row_num = rows
            try:
                strRows = allLines[row_num]
            except Exception:
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50204"] %
                                ("the %s line of the file [%s]" % (rows, filename)))
        # check which needs return
        if (keyword != "" and rows != 0):
            return [strRows]
        if (keyword != "" and rows == 0):
            return listKey
        if (keyword == "" and rows != 0):
            return [strRows]
        if (keyword == "" and rows == 0):
            return allLines


    @staticmethod
    def writeFile(path, context=None, mode="a+"):
        """
        function: write content in a file
        input:
            path: the name and path of the file
            context: the content, which want to write
            mode: the write mode
        output:
        """
        if context is None:
            context = []
        lock = thread.allocate_lock()
        # check if not exists.
        if (not os.path.exists(path)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % path)
        # check if is a file.
        if (os.path.exists(path) and not os.path.isfile(path)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50210"] % path)
        # if no context, return
        if not context:
            return True
        fp = open(path, mode)
        fp.writelines(line + os.linesep for line in context)
        lock.acquire()
        try:
            # write context.
            fp.flush()
            fp.close()
        except Exception as e:
            fp.close()
            lock.release()
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50205"] % path + "Error:\n%s" % str(e))
        lock.release()
        return True

    @staticmethod
    def cleanFileContext(path):
        """
        """
        realPath = os.path.realpath(path)
        if (os.path.exists(realPath) and os.path.getsize(realPath) > 0):
            with open(realPath, 'r+') as f:
                f.seek(0)
                f.truncate()
                f.flush()

    @staticmethod
    def withAsteriskPath(path):
        """
        function: deal with the path with *
        input: the path to deal with
        output: cmd
        """
        path_dirList = os.path.realpath(path).split(os.path.sep)[1:]
        path = "'"
        for dirName in path_dirList:
            if ("*" in dirName):
                dirPath = "'" + os.path.sep + dirName + "'"
            else:
                dirPath = os.path.sep + dirName
            path += dirPath
        if (path[-1] == "'"):
            path = path[:-1]
        else:
            path += "'"
        return path

    def changeMode(self, mode, path, recursive=False, cmdType="shell", retryFlag=False, retryTime=15, waiteTime=1):
        """
        function: change permission of file
        input:
            cmdType: user shell or python
            mode:permission value, Type is int and start with 0. ex: 0700
            path:file path
            recursive: recursive or not
        output:
        """
        try:
            # do with shell command.
            if (cmdType == "shell"):
                if ("*" in path):
                    path = self.withAsteriskPath(path)
                else:
                    path = "'" + path + "'"
                cmd = g_Platform.getChmodCmd(str(mode), path, recursive)
                if (retryFlag):
                    self.retryGetstatusoutput(cmd, retryTime, waiteTime)
                else:
                    (status, output) = subprocess.getstatusoutput(cmd)
                    if (status != 0):
                        raise Exception(ErrorCode.GAUSS_501["GAUSS_50107"] % path + " Error:\n%s" % output)
            # do with python API. If the name has special characters.
            else:
                os.chmod(path, mode)
        except Exception as e:
            raise Exception(str(e))
        return True

    def changeOwner(self, user, path, recursive=False, cmdType="shell", retryFlag=False, retryTime=15, waiteTime=1):
        """
        function: change the owner of file
        input: cmdType, user, path, recursive
        output: return true
        """
        try:
            # get uid and gid by username.
            userInfo = pwd.getpwnam(user)
            uid = userInfo.pw_uid
            gid = userInfo.pw_gid
            group = grp.getgrgid(gid).gr_name
        except Exception as e:
            raise Exception(ErrorCode.GAUSS_503["GAUSS_50308"] + " Error:\n%s" % str(e))
        try:
            # do with shell command.
            if (cmdType == "shell"):
                if ("*" in path):
                    path = self.withAsteriskPath(path)
                else:
                    path = "'" + path + "'"
                cmd = g_Platform.getChownCmd(user, group, path, recursive)
                if (retryFlag):
                    self.retryGetstatusoutput(cmd, retryTime, waiteTime)
                else:
                    (status, output) = subprocess.getstatusoutput(cmd)
                    if (status != 0):
                        raise Exception(output)
            # do with python API. If the name has special characters.
            else:
                os.chown(path, uid, gid)
        except Exception as e:
            raise Exception(ErrorCode.GAUSS_501["GAUSS_50106"] % path + " Error:\n%s." % str(e))
        return True

    @staticmethod
    def retryGetstatusoutput(cmd, retryTime, sleepTime):
        """
        function : exectue commands, if fail ,then retry it.
        input : cmd, waitTimes, retryTimes
        output: NA
        """
        countNum = 0
        (status, output) = subprocess.getstatusoutput(cmd)
        while (countNum < retryTime):
            if (status != 0):
                sleepCmd = "sleep %s" % sleepTime
                subprocess.getstatusoutput(sleepCmd)
                (status, output) = subprocess.getstatusoutput(cmd)
                countNum = countNum + 1
            else:
                break
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_501["GAUSS_51400"] % cmd + " Error:\n%s" % output)

    @staticmethod
    def createDirectory(path, overwrite=True, mode=None):
        """
        function: create a directory
        input: path, overwrite
        output: true
        """
        try:
            if (os.path.exists(path) and not overwrite):
                raise Exception(ErrorCode.GAUSS_501["GAUSS_50102"] % ("parameter overwrite", path))
            if (overwrite):
                cmd = g_Platform.getMakeDirCmd(path, overwrite)
                if (mode):
                    cmd += "; %s" % g_Platform.getChmodCmd(str(mode), path)
                (status, output) = subprocess.getstatusoutput(cmd)
                if (status != 0):
                    raise Exception(output)
            if not overwrite:
                if (mode):
                    os.mkdir(path, mode)
                else:
                    os.mkdir(path)
        except Exception as e:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50208"] % path + " Error:\n%s" % str(e))
        return True

    @staticmethod
    def cleanDirectoryContent(path):
        """
        function: clean the content in a directory, but do not remove directory.
        input:path
        output:true
        """
        if (not os.path.exists(path)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % path)
        cmd = "%s '%s/'* && %s '%s'/.[^.]*" % \
              (g_Platform.getRemoveCmd("directory"), path, g_Platform.getRemoveCmd("directory"), path)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50209"] %
                            ("content in the directory %s " % path) + " Error:\n%s" % output)
        return True

    def removeDirectory(self, path):
        """
        function: remove the content in a directory
        input:path
        output:true
        """
        if ("*" in path):
            path = self.withAsteriskPath(path)
            cmd = "%s %s" % (g_Platform.getRemoveCmd("directory"), path)
        else:
            cmd = "%s '%s'" % (g_Platform.getRemoveCmd("directory"), path)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50209"] % path + " Error:\n%s" % output)
        return True

    @staticmethod
    def moveDirectory(src, dest):
        """
        function:move the content in a directory
        input:src, dest
        output:true
        """
        if (not os.path.exists(src)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % src)
        if (not os.path.exists(dest)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % dest)
        cmd = g_Platform.getMoveCmd(src, dest)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_514["GAUSS_51400"] % cmd + " Error:\n%s" % output)
        return True

    @staticmethod
    def getDirectoryList(path, keywords="", recursive=False):
        """
        function:give the list of file in the directory
        input:path, keywords, recursive
        output:list
        """
        list_Dir = []
        try:
            if (keywords == ""):
                if (recursive):
                    cmd = "%s -R '%s'" % (g_Platform.getListCmd(), path)
                    (status, output) = subprocess.getstatusoutput(cmd)
                    if (status != 0):
                        raise Exception(output)
                    list_Dir = output.split('\n')
                else:
                    list_Dir = os.listdir(path)
            else:
                if (recursive):
                    cmd = "%s -R '%s' |%s -E '%s'" % (g_Platform.getListCmd(), path, g_Platform.getGrepCmd(), keywords)
                else:
                    cmd = "%s '%s' |%s -E '%s'" % (g_Platform.getListCmd(), path, g_Platform.getGrepCmd(), keywords)
                (status, output) = subprocess.getstatusoutput(cmd)
                if (status != 0 and output != ""):
                    raise Exception(output)
                else:
                    list_Dir = output.split('\n')
        except Exception as e:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50219"] % ("the list of %s" % path) + " Error:\n%s" % str(e))
        while ('' in list_Dir):
            list_Dir.remove('')
        return list_Dir

    @staticmethod
    def cpFile(src, dest, cmdType="shell", skipCheck=False):
        """
        function: copy a file
        input:src, dest, cmdType
        output:true
        """
        if (skipCheck):
            if (not os.path.exists(src)):
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % src)
            if (not os.path.exists(os.path.dirname(dest))):
                raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % os.path.dirname(dest))
        try:
            if (cmdType != "shell"):
                shutil.copy(src, dest)
            else:
                cmd = g_Platform.getCopyCmd(src, dest, "directory")
                (status, output) = subprocess.getstatusoutput(cmd)
                if (status != 0):
                    raise Exception(output)
        except Exception as e:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50214"] % src + " Error:\n%s" % str(e))
        return True

    @staticmethod
    def findFile(path, keyword, choice='name'):
        """
        function:find a file by name or size or user
        input:path, keyword, choice, type
        output:NA
        """
        if (not os.path.exists(path)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % path)
        cmd = "%s '%s' -%s %s " % (g_Platform.getFindCmd(), path, choice, keyword)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50219"] %
                            ("the files of path %s" % path) + " Error:\n%s" % output)
        list_File = output.split('\n')
        while '' in list_File:
            list_File.remove('')
        return list_File

    @staticmethod
    def compressFiles(tarName, dirPath):
        """
        function:compress directory to a package
        input:tarName, directory
        output:NA
        """
        cmd = g_Platform.getCompressFilesCmd(tarName, dirPath)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50227"] % cmd + " Error:\n%s" % output)

    @staticmethod
    def decompressFiles(srcPackage, dest):
        """
        function:decompress package to files
        input:srcPackage, dest
        output:NA
        """
        if (not os.path.exists(srcPackage)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % srcPackage)
        if (not os.path.exists(dest)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % dest)
        cmd = g_Platform.getDecompressFilesCmd(srcPackage, dest)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50231"] % srcPackage + " Error:\n%s" % output)

    @staticmethod
    def compressZipFiles(zipName, dirPath):
        """
        function:compress directory to a package
        input:zipName, directory
        output:NA
        """
        if (not os.path.exists(dirPath)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % dirPath)
        cmd = g_Platform.getCompressZipFilesCmd(zipName, dirPath)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50227"] % cmd + " Error:\n%s" % output)

    @staticmethod
    def decompressZipFiles(srcPackage, dest):
        """
        function:decompress package to files
        input:srcPackage, dest
        output:NA
        """
        if (not os.path.exists(srcPackage)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % srcPackage)
        if (not os.path.exists(dest)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % dest)
        cmd = g_Platform.getDecompressZipFilesCmd(srcPackage, dest)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50231"] % srcPackage + " Error:\n%s" % output)

    @staticmethod
    def getfileUser(path):
        """
        function: get the info(username group) of a file
        input:path
        output:list of info
        """
        if (not os.path.exists(path)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % path)

        user = pwd.getpwuid(os.stat(path).st_uid).pw_name
        group = grp.getgrgid(os.stat(path).st_gid).gr_name
        return user, group

    @staticmethod
    def replaceFileLineContent(oldLine, newLine, path):
        """
        function: replace the line in a file to a new line
        input:
        oldLine : Need to replace content
        newLine : Replaced content
        path
        output:NA
        """
        if (not os.path.exists(path)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % path)

        cmd = g_Platform.getReplaceFileLineContentCmd(oldLine, newLine, path)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50223"] % path + " Error:\n%s" % output)

    @staticmethod
    def getPermission(dirPath):
        """
        function : Get the permission of the directory
        input : String
        output : String
        """
        if (not os.path.exists(dirPath)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % dirPath)
        try:
            value = oct(os.stat(dirPath).st_mode)[-3:]
        except Exception as e:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50219"] %
                            ("permission with %s" % dirPath) + " Error:\n%s" % str(e))
        return value

    @staticmethod
    def checkIsInDirectory(fileName, directoryList):
        """
        function : Check if the file is in directoryList.
        input : String,[]
        output : []
        """
        try:
            isExist = False
            for onePath in directoryList:
                dirName = os.path.normpath(fileName)
                isExist = False

                while (dirName != "/"):
                    if (dirName == onePath):
                        isExist = True
                        break
                    dirName = os.path.dirname(dirName)

                if (isExist):
                    raise Exception(ErrorCode.GAUSS_502["GAUSS_50229"] % (fileName, onePath))
        except Exception as e:
            raise Exception(str(e))
        return isExist

    @staticmethod
    def checkDirWriteable(dirPath):
        """
        function : Check if target directory is writeable for execute user.
        input : String,String
        output : boolean
        """
        # if we can touch a tmp file under the path, it is true;
        return os.access(dirPath, os.W_OK)

    @staticmethod
    def checkFilePermission(filename, isread=False, iswrite=False, isexecute=False):
        """
        Function : check file: 1.exist 2. isfile 3. permission
        Note     : 1.You must check that the file exist and is a file.
                   2.You can choose whether to check the file's permission:readable/writable/executable.
        input : filename, isread, iswrite, isexecute
        output : True
        """
        if (not os.path.exists(filename)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % filename)
        if (not os.path.isfile(filename)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50210"] % filename)
        if (isread):
            if (not os.access(filename, os.R_OK)):
                raise Exception(ErrorCode.GAUSS_501["GAUSS_50100"] %
                                (filename, "the user") + " Error:\n%s: Permission denied." % filename)
        if (iswrite):
            if (not os.access(filename, os.W_OK)):
                raise Exception(ErrorCode.GAUSS_501["GAUSS_50102"] %
                                (filename, "the user") + " Error:\n%s: Permission denied." % filename)
        if (isexecute):
            if (not os.access(filename, os.X_OK)):
                raise Exception(ErrorCode.GAUSS_501["GAUSS_50101"] %
                                (filename, "the user") + " Error:\n%s: Permission denied." % filename)
        return True

    @staticmethod
    def getFileSHA256(filename):
        """
        function : Get the ssh file by SHA256
        input : String
        output : String
        """
        if (not os.path.exists(filename)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % filename)
        if (not os.path.isfile(filename)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50210"] % filename)

        strSHA256 = ""
        cmd = g_Platform.getFileSHA256Cmd(filename)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            return strSHA256
        strSHA256 = output.strip()

        return strSHA256

    @staticmethod
    def getDirSize(path, unit=""):
        """
        function : Get the directory or file size
        input : String, String
        output : String
        """
        sizeInfo = ""
        cmd = g_Platform.getDirSizeCmd(path, unit)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            return sizeInfo
        return output.split()[0]

    @staticmethod
    def getTopPath(path):
        """
        function: find the top path of the specified path
        input : NA
        output: tmpDir
        """
        tmpDir = path
        while True:
            # find the top path to be created
            (tmpDir, topDirName) = os.path.split(tmpDir)
            if (os.path.exists(tmpDir) or topDirName == ""):
                tmpDir = os.path.join(tmpDir, topDirName)
                break
        return tmpDir

    @staticmethod
    def getFilesType(givenPath):
        """
        function : get the file and subdirectory type of the given path
        input : String
        output : String
        """
        if (not os.path.exists(givenPath)):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50201"] % givenPath)
        # obtain the file type
        tmpFile = "/tmp/fileList_%d" % os.getpid()
        cmd = "%s '%s' ! -iname '.*' | %s file -F '::' > %s 2>/dev/null" % \
              (g_Platform.getFindCmd(), givenPath, g_Platform.getXargsCmd(), tmpFile)
        os.system(cmd)
        # Return code is not equal to zero when file a non-existent file in SLES SP4
        # But it is equal to zero in SLES SP1/SP2/SP3 and RHEL 6.4/6.5/6.6 platform, skip check status and output
        fp = None
        resDict = {}
        try:
            fp = open(tmpFile, 'r')
            fileNameTypeList = fp.readlines()
            fp.close()
            os.remove(tmpFile)
            for oneItem in fileNameTypeList:
                res = oneItem.split("::")
                if (len(res) != 2):
                    continue
                else:
                    resDict[res[0]] = res[1]
            return resDict
        except Exception as e:
            if fp:
                fp.close()
            if (os.path.exists(tmpFile)):
                g_file.removeFile(tmpFile)
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50221"] + " Error: \n%s" % str(e))

    @staticmethod
    def deleteLine(filePath, lineInfo):
        """
        function : delete line in a file
        input : filePath ,lineInfo
        output : NA
        """
        cmd = g_Platform.getSedCmd()
        cmd += " -i '/%s/d' %s" % (lineInfo, filePath)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50205"] % filePath + " Error:\n%s" % output)

    @staticmethod
    def deleteLineByRowNum(filePath, lineNum):
        """
        function : delete line in a file by row num
        input : filePath ,lineInfo
        output : NA
        """
        cmd = g_Platform.getSedCmd()
        cmd += " -i '%sd' %s" % (lineNum, filePath)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50205"] % filePath + " Error:\n%s" % output)

    @staticmethod
    def deleteLineByRange(filePath, lineNum1, lineNum2):
        """
        function : delete line in a file by row num
        input : filePath ,lineInfo
        output : NA
        """
        cmd = g_Platform.getSedCmd()
        cmd += " -i '%s,%sd' %s" % (lineNum1, lineNum2, filePath)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50205"] % filePath + " Error:\n%s" % output)

    @staticmethod
    def rename(oldFilePath, newFilePath):
        """
        function : rename a file name to new name
        input : oldFilePath, newFilePath
        output : NA
        """
        cmd = g_Platform.getMoveCmd(oldFilePath, newFilePath)
        (status, output) = subprocess.getstatusoutput(cmd)
        if status != 0:
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50218"] % oldFilePath + " Error:\n%s" % output)

    @staticmethod
    def echoLineToFile(line, filePath):
        """
        function : write line in file
        input : line, file
        output : use 2>/dev/null, no return.
        Notice: maye the line has '$'
        """
        cmd = g_Platform.echoCmdWithNoReturn(line, filePath)
        (status, output) = subprocess.getstatusoutput(cmd)
        if (status != 0):
            raise Exception(ErrorCode.GAUSS_502["GAUSS_50205"] % filePath + " Command:%s. Error:\n%s" % (cmd, output))

    @staticmethod
    def generateJsonFile(jsonFile, jsonDict):
        """
        function: generate json file for dbClusterInfo object,
                  or other dict dumped from json
        input: jsonFile - the json file
        output: NA
        """
        flags = os.O_WRONLY | os.O_CREAT
        modes = stat.S_IWUSR | stat.S_IRUSR
        try:
            with os.fdopen(os.open(jsonFile, flags, modes), "w") as fp:
                json.dump(jsonDict, fp)
        except Exception as error:
            raise Exception(str(error))

    @staticmethod
    def parseJsonFile(jsonFile):
        """
        function: parse json configure file and return json object dict
        input: json configure file
        output: json dict object
        """
        try:
            with open(jsonFile, 'r') as fp:
                rootDict = json.load(fp)
            return rootDict
        except Exception as error:
            raise Exception(str(error))

    @staticmethod
    def write_file_with_default_permission(file, lines, write_line=True, default_type="w"):
        """
        function: write file with appropriate permissions
        input: file
        output: NA
        """
        flags = os.O_WRONLY | os.O_CREAT | os.O_TRUNC
        modes = stat.S_IWUSR | stat.S_IRUSR
        with os.fdopen(os.open(file, flags, modes), default_type) as fp:
            if write_line:
                fp.writelines(lines)
            else:
                fp.write(lines)


g_file = fileManage()
