#!/usr/bin/env python3
#-*- coding:utf-8 -*-
try:
    import sys
    import importlib
    importlib.reload(sys)
    import os
    from gspylib.inspection.common.CheckItem import BaseItem
except ImportError as ie:
    raise Exception("[GAUSS-52200] : Unable to import module: %s." % str(ie))


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

    def getClusterDirectorys(self, dbNode):
        """
        function : Get cluster all directorys
        input : NA
        output : List
        """
        nodeDirs = []
        # including cm_server, cm_agent, cn, dn, gtm, etcd, ssd
        nodeDirs.append(dbNode.cmDataDir)
        for dbInst in dbNode.cmservers:
            nodeDirs.append(dbInst.datadir)
        for dbInst in dbNode.cmagents:
            nodeDirs.append(dbInst.datadir)
        for dbInst in dbNode.gtms:
            nodeDirs.append(dbInst.datadir)
        for dbInst in dbNode.coordinators:
            nodeDirs.append(dbInst.datadir)
            if (hasattr(dbInst, 'ssdDir') and len(dbInst.ssdDir) != 0):
                nodeDirs.append(dbInst.ssdDir)
        for dbInst in dbNode.datanodes:
            nodeDirs.append(dbInst.datadir)
            if (hasattr(dbInst, 'ssdDir') and len(dbInst.ssdDir) != 0):
                nodeDirs.append(dbInst.ssdDir)
        if (hasattr(dbNode, 'etcds')):
            for dbInst in dbNode.etcds:
                nodeDirs.append(dbInst.datadir)
        return nodeDirs

    def getTableSpacePath(self, dirPath):
        tableSpaceDir = os.path.join(dirPath, "pg_tblspc")
        tableSpaceList = os.listdir(tableSpaceDir)
        tablespacePaths = []
        if(len(tableSpaceList)):
            for filename in tableSpaceList:
                if(os.path.islink(os.path.join(tableSpaceDir, filename))):
                    linkDir = os.readlink(os.path.join(tableSpaceDir, filename))
                    if(os.path.isdir(linkDir)):
                        tablespacePaths.append(linkDir)
        return tablespacePaths

    def doCheck(self):
        self.result.val = ""
        nodeInfo = self.cluster.getDbNodeByName(self.host)
        clusterPathList = self.getClusterDirectorys(nodeInfo)
        clusterPathList.append(self.cluster.appPath)
        clusterPathList.append(self.cluster.logPath)
        clusterPathList.append(os.getenv('GPHOME'))
        clusterPathList.append(os.getenv('PGHOST'))

        nodeInfo = self.cluster.getDbNodeByName(self.host)
        if self.cluster.isSingleInstCluster():
            dirPath = nodeInfo.datanodes[0].datadir
        else:
            dirPath = nodeInfo.coordinators[0].datadir

        tablespacePaths = self.getTableSpacePath(dirPath)
        flag = "Normal"
        for tableSpace in tablespacePaths:
            if tableSpace.find(' ') >= 0:
                flag = "Error"
                self.result.val += "Table space path[%s] contains spaces.\n" % tableSpace
            # Support create tablespace in pg_location dir for V1R7
            if tableSpace.find(os.path.join(dirPath, "pg_location")) == 0:
                continue
            tableSpaces = tableSpace.split('/')
            for clusterPath in clusterPathList:
                clusterPaths = clusterPath.split('/')
                if tableSpace.find(clusterPath) == 0 and tableSpaces[:len(clusterPaths)] == clusterPaths:
                    if flag == "Normal":
                        flag = "Warning"
                    self.result.val += "Table space path[%s] and cluster path[%s] are nested.\n"\
                                       % (tableSpace, clusterPath)
                elif clusterPath.find(tableSpace) == 0 and clusterPaths[:len(tableSpaces)] == tableSpaces:
                    flag = "Error"
                    self.result.val += "Table space path[%s] and cluster path[%s] are nested.\n"\
                                       % (tableSpace, clusterPath)
                else:
                    continue
        for tableSpace1 in tablespacePaths:
            tableSpaces1 = tableSpace1.split('/')
            for tableSpace2 in tablespacePaths:
                if tableSpace1 == tableSpace2:
                    continue
                tableSpaces2 = tableSpace2.split('/')
                if tableSpace1.find(tableSpace2) == 0 and tableSpaces1[:len(tableSpaces2)] == tableSpaces2:
                    flag = "Error"
                    self.result.val += "Table space path[%s] and table space path[%s] are nested.\n"\
                                       % (tableSpace1, tableSpace2)

        self.judge_status_by_flag(flag, "All table space path is normal.")
