import logging
import os
import stat
from queue import Queue
from subprocess import getstatusoutput
from threading import Thread

from scripts.verifyGaussPython.src.python.PropertyFile import get_encoding_format, get_encoding_format_from_shell
from scripts.verifyGaussPython.src.python.run_utils import rungauss100scriptfile_file, rungauss200scriptfile
from scripts.verifyGaussPython.src.python.shell_utils import setquerycount, getquerycount

class ImportDDLToGauss(Thread):
    def __init__(self, queue, configdata, homepath, outputfolder, logpath):
        Thread.__init__(self)
        self.queue = queue
        self.configdata = configdata
        self.homepath = homepath
        self.outputfolder = outputfolder
        self.logpath = logpath

    def run(self):
        dbtype = self.configdata['gaussdb-type']
        username = self.configdata['gaussdb-user']
        password = self.configdata['gaussdb-password']
        port = self.configdata['gaussdb-port']
        successoutputfile = os.path.join(self.logpath, 'gaussexecutionlog.log')
        errorlogfile = os.path.join(self.logpath, 'gaussexecutionerror.log')
        outputfolderfile = self.outputfolder

        ip = self.configdata['gaussdb-ip']
        if dbtype == "gaussdbt":
            while True:
                filename = self.queue.get()
                if filename is None:
                    return
                fl = None
                try:
                    encoding = get_encoding_format(self.homepath)
                    if encoding is None:
                        encoding = get_encoding_format_from_shell(filename)
                    with open(filename, 'r', encoding=encoding) as fl:

                        lines = fl.readlines()
                        mapfilename = os.path.join(outputfolderfile, 'rangeMapper',
                                                   filename.split(outputfolderfile)[1].split('output', 1)[1].replace(
                                                       '/', '', 1))
                        with open(mapfilename, 'r') as mpfl:
                            tempfile = mapfilename + ".txt"
                            if os.path.exists(tempfile):
                                cmd = "rm {0} ".format(tempfile)
                                getstatusoutput(cmd)
                            if not os.path.exists(tempfile):
                                cmd = "touch {0} ".format(tempfile)
                                getstatusoutput(cmd)
                                cmd = "chmod 600 {0} ".format(tempfile)
                                getstatusoutput(cmd)

                            maplines = mpfl.readlines()
                            flag = True
                            for mline in maplines:
                                string = ""
                                if len(mline) > 3:
                                    mline = mline.replace("\n", "")
                                    mlinelist = mline.split(",")
                                    listquery = lines[int(mlinelist[0]) - 1:int(mlinelist[1])]
                                    string = string.join(listquery)
                                    tpfile = os.fdopen(os.open(tempfile, os.O_WRONLY | os.O_CREAT, 0o640), 'a')
                                    tpfile.writelines(string)
                                    tpfile.close()

                                    rungauss100scriptfile_file(ip, port, username, password, tempfile,
                                                               successoutputfile, errorlogfile, filename,
                                                               int(mlinelist[0]), flag)
                                    flag = False
                                    tempfilename = os.fdopen(os.open(tempfile, os.O_WRONLY | os.O_CREAT, 0o640), 'a')
                                    tempfilename.truncate(0)
                                    tempfilename.close()

                            mpfl.close()
                        setquerycount(getquerycount() + 1)
                except (KeyboardInterrupt, Exception) as error:
                    setquerycount(getquerycount() + 1)
                    logging.error("Error occurred during query execution to gaussdb %s", error)

                finally:
                    if fl is not None:
                        fl.close()

        else:
            dbname = self.configdata['gaussdb-name']
            while True:
                filename = self.queue.get()
                if filename is None:
                    return
                try:
                    rungauss200scriptfile(dbname, port, username, password, ip, filename, successoutputfile,
                                          errorlogfile)
                except (KeyboardInterrupt, Exception) as error:
                    logging.error("Error occurred during query execution to gaussdb %s", error)


def gaussdbexecutiontask(folder_path, configdata, homepath, outputfolder, logpath):
    """ Gauss db execution thread start """
    queue = Queue()
    dbtype = configdata['gaussdb-type']
    if dbtype == 'gaussdba':
        threadcountA = int(configdata['gaussdbathreadcount'])
        for _ in range(threadcountA):
            thread = ImportDDLToGauss(queue, configdata, homepath, outputfolder, logpath)
            thread.daemon = True
            thread.start()
        for fle in sorted(folder_path[2], key=str.lower):
            filename = os.path.join(folder_path[0], fle)
            queue.put(filename)
        for _ in range(threadcountA):
            queue.put(None)
    else:
        threadcountT = 1
        for _ in range(threadcountT):
            thread = ImportDDLToGauss(queue, configdata, homepath, outputfolder, logpath)
            thread.daemon = True
            thread.start()
        for fle in sorted(folder_path[2], key=str.lower):
            filename = os.path.join(folder_path[0], fle)
            queue.put(filename)
        for _ in range(threadcountT):
            queue.put(None)
