import subprocess
import pathlib
import re

import plugins.agl_test_conf as conf
from plugins.agl_test_base import AGLBaseTest

class LTPBase(AGLBaseTest):

    LTPDIR = "/opt/ltp/"
    RUNLTP = LTPDIR + "runltp"
    LTPTEST = LTPDIR + "runtest/"

    #Test name without the prefix of "LTP/"
    test_name: str

    def __init__(self, test_name: str):
        self.test_name = test_name
        super().__init__(name = ("LTP/" + test_name))

        #Check and clean exit log
        tmp_log_dir = self.get_log_path()
        log_file = self.get_log_file()
        log_path = pathlib.Path(log_file)
        check_log_path = log_path.is_file()
        if check_log_path:
            subprocess.run("rm " + tmp_log_dir + "*", shell = True)

    def get_log_path(self):
        return self.get_temp_logdir() + "/log/"

    def get_log_file(self):
        return self.get_log_path() + self.test_name + ".log"

    def get_test_case_list(self):
        case_list = list()
        reObj = re.compile('^([\\w\\-]+)(\\s+)(\\w+)', re.MULTILINE)

        test_file = self.LTPTEST + self.test_name
        test_cases = open(test_file, 'r')
        line = test_cases.readline()
        while line:
            matchs = reObj.search(line)
            if matchs:
                groups = matchs.groups()
                case_list.append(groups[0])
            line = test_cases.readline()

        test_cases.close()
        return case_list

    #Run test by runltp
    def run_test_fun(self, case_name):
        tmp_log_dir = self.get_log_path()
        run_test_cmd = self.RUNLTP + \
            " -f " + self.test_name + \
            " -s "+ "^" + case_name + "\\\\b" + \
            " -p " + \
            " -o " + tmp_log_dir + self.test_name + ".output " + \
            " -l " + tmp_log_dir + self.test_name + ".log " + \
            " -C " + tmp_log_dir + self.test_name + ".failed " + \
            " -T " + tmp_log_dir + self.test_name + ".tconf "

        console_log = tmp_log_dir + self.test_name + ".console"

        with open(console_log, 'a') as consolelog:
            subprocess.run(run_test_cmd, shell = True, stdout = consolelog,
                stderr = consolelog)
        consolelog.close()

    def run_case(self, case_id):
        case_info = self.get_caseinfo_by_name(case_id)
        if (case_info[2] == ""):
            if (case_info[1] == "PASS"):
                case_info[2] = "passed"
            elif (case_info[1] == "FAIL"):
                case_info[2] = "failed"
            #The following situations will be determined as "skipped"
            # "CONF" "UNRESOLVED" "UNSUPPORTED" "UNTESTED" ""
            else:
                case_info[2] = "skipped"

        self.update_caseinfo_by_name(case_id, case_info)
        assert case_info[2] == "passed" or case_info[2] == "skipped"

    def precheck(self):
        # Check for common
        check_common = super().precheck()

        # Check for runltp script
        runltp_script = pathlib.Path(self.RUNLTP)
        check_runltp_script = runltp_script.is_file()

        # Check self test file
        test_file = pathlib.Path(self.LTPTEST + self.test_name)
        check_test_file = test_file.is_file()

        return check_common and check_runltp_script and check_test_file

    def log_process(self):
        log_file = self.get_log_file()
        case_result = self.log_parser(log_file)
        self.case_info_list[case_result[0]] = [case_result[0], case_result[2], ""]

    #Log sample:
    #Testcase           Result     Exit Value
    #--------           ------     ----------
    #cve-2011-0999      PASS       0
    #cve-2011-2183      CONF       32
    #cve-2011-2496      FAIL       1
    def log_parser(self, log_file):
        reObj = re.compile('^(.+\\w+)( +)(PASS|CONF|FAIL)( +)(\\d+)', re.MULTILINE)
        case_list = dict()
        test_log = open(log_file, 'r')

        lines = test_log.readlines()
        num = -1
        line = lines[num]
        while line:
            matchs = reObj.search(line)

            if matchs:
                groups = matchs.groups()
                test_log.close()
                return groups

            num = num - 1
            line = lines[num]

        test_log.close()

    def run_ltp_test(self, case_name):
        if(self.precheck() == True):
            self.run_test_fun(case_name)
            self.log_process()