# -*- coding: utf-8 -*-
# @Time : 2021/11/25 19:56
# @Author : wangyinghao
# @Site :
# @File : run_test_plan_task.py
# @Software: PyCharm
import django
import json
import os
import re
import sys
from os.path import dirname, abspath

BASE_DIR = dirname(dirname(dirname(abspath(__file__))))
BASE_PATH = BASE_DIR.replace("\\", "/")
sys.path.append(BASE_PATH)
curPath = os.path.abspath(os.path.dirname(__file__))
rootPath = os.path.split(curPath)[0]
sys.path.append(rootPath)
sys.path.extend(['/home/AutomatedTestPlatform'])
# project_name 项目名称
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "AutomatedTestPlatform.settings")
django.setup()
from automated_main.models.api_automation.api_interfaces_case import ApiInterfacesParameterExtraction
from automated_main.models.api_automation.api_test_plan import APITestPlanResultAssociated
from automated_main.utils.handle_db import HandleDB
from automated_main.models.api_automation.api_database import APIDatabase
from automated_main.utils.api_utils import RegularMatch
from automated_main.utils.api_utils import InterfaceRequest
import logging
import ast

logger = logging.getLogger('django')

logger.info("运行测试文件：" + BASE_PATH)

# 定义扩展的目录
EXTEND_DIR = BASE_PATH + "/api_test_plan/extend/"
logger.info("地址信息" + EXTEND_DIR)


def new_test_run_cases(case_id):
    for case in case_id:
        api_test_case_id = (case['api_test_case_id'])
        api_test_case_name = (case['api_test_case_name'])
        api_url = (case['api_url'])
        api_method = (case['api_method'])
        api_parameter_types = (case['api_parameter_types'])
        api_headers = (case['api_headers'])
        api_parameter_body = (case['api_parameter_body'])
        api_assert_type = (case['api_assert_type'])
        api_parameter_extraction = (case['api_parameter_extraction'])
        parameter_data = (case['parameter_data'])
        api_assert_text = (case['api_assert_text'])
        api_result_id = (case['api_result_id'])
        api_task_id = (case['api_task_id'])
        database_id = (case['dataBase_id'])
        database_sql = (case['database_sql'])
        api_business_test_name = (case['api_scenarios_case_name'])
        api_environment_id = (case['api_environment_id'])
        api_assertion_results = ""
        api_error = ""
        api_successful = ""
        api_variable_results = ""
        abnormal = ""
        json_loads = ""

        try:

            api_url = RegularMatch(api_url, api_environment_id, "1", regular="new")

            # if "${" in api_url and "}" in api_url:
            #     key = re.findall(r"\${(.+?)}", api_url)
            #     for a in range(len(key)):
            #         key1 = "${" + key[a] + "}"
            #
            #         api_global_variable = APIGlobalVariable.objects.filter(api_global_variable_name=key1,
            #                                                                api_environment_id=api_environment_id)
            #         if api_global_variable.count() > 0:
            #             variable = api_global_variable[0].api_global_variable_value
            #             api_url = api_url.replace(key1, variable)
            #         else:
            #             value_variable = ApiParameterExtraction.objects.filter(api_key_variable=key1)
            #             variable = value_variable[0].api_variable_results
            #             api_url = api_url.replace(key1, variable)

            if api_headers == "{}" or "":
                header_dict = {}

            else:
                api_headers = RegularMatch(api_headers, api_environment_id, "1", regular="new")

                # if "${" in api_headers and "}" in api_headers:
                #     key = re.findall(r"\${(.+?)}", api_headers)
                #     for b in range(len(key)):
                #         key1 = "${" + key[b] + "}"
                #
                #         api_global_variable = APIGlobalVariable.objects.filter(api_global_variable_name=key1,
                #                                                                api_environment_id=api_environment_id)
                #         if api_global_variable.count() > 0:
                #             variable = api_global_variable[0].api_global_variable_value
                #             api_headers = api_headers.replace(key1, variable)
                #         else:
                #             value_variable = ApiParameterExtraction.objects.filter(api_key_variable=key1)
                #             variable = value_variable[0].api_variable_results
                #             api_headers = api_headers.replace(key1, variable)

                header = api_headers.replace("\'", "\"")

                header_dict = json.loads(header)

            if api_parameter_body == "{}" or "":
                api_parameter_body_dict = {}
            else:
                api_parameter_body = RegularMatch(api_parameter_body, api_environment_id, "1", regular="new")

                # if "${" in api_parameter_body and "}" in api_parameter_body:
                #     key = re.findall(r"\${(.+?)}", api_parameter_body)
                #     for b in range(len(key)):
                #         key1 = "${" + key[b] + "}"
                #
                #         api_global_variable = APIGlobalVariable.objects.filter(api_global_variable_name=key1,
                #                                                                api_environment_id=api_environment_id)
                #         if api_global_variable.count() > 0:
                #             variable = api_global_variable[0].api_global_variable_value
                #             api_parameter_body = api_parameter_body.replace(key1, variable)
                #         else:
                #
                #             value_variable = ApiParameterExtraction.objects.filter(api_key_variable=key1)
                #             variable = value_variable[0].api_variable_results
                #             api_parameter_body = api_parameter_body.replace(key1, variable)

                api_parameter = api_parameter_body.replace("\'", "\"")
                api_parameter_body_dict = json.loads(api_parameter)

            if parameter_data == "{}" or "":
                data_payload = {}
            else:
                parameter_data_task = RegularMatch(str(parameter_data), api_environment_id, "1", regular="new")
                data_payload = ast.literal_eval(parameter_data_task)

                # if "${" in parameter_data and "}" in parameter_data:
                #     key = re.findall(r"\${(.+?)}", parameter_data)
                #     for b in range(len(key)):
                #         key1 = "${" + key[b] + "}"
                #
                #         api_global_variable = APIGlobalVariable.objects.filter(api_global_variable_name=key1,
                #                                                                api_environment_id=api_environment_id)
                #         if api_global_variable.count() > 0:
                #             variable = api_global_variable[0].api_global_variable_value
                #             parameter_data = parameter_data.replace(key1, variable)
                #         else:
                #
                #             value_variable = ApiParameterExtraction.objects.filter(api_key_variable=key1)
                #             variable = value_variable[0].api_variable_results
                #             parameter_data = parameter_data.replace(key1, variable)

            r = InterfaceRequest(str(api_method), str(api_parameter_types), api_url, header_dict,
                                 api_parameter_body_dict, data_payload)

            logger.info("测试用例名称： %s", api_test_case_name)
            logger.info("请求地址： %s", r.url)
            logger.info("请求json数据： %s", api_parameter_body_dict)
            logger.info("请求parameter数据： %s", data_payload)
            logger.info("请求头： %s", r.headers)
            logger.info("请求响应： %s", r.text)
            if r == "请求超时":
                api_error = 1
                api_successful = 0
                APITestPlanResultAssociated.objects.create(api_test_case_name=api_test_case_name, api_error=api_error,
                                                           api_successful=api_successful, abnormal=abnormal,
                                                           json_extract_variable_conversion=json_loads,
                                                           api_assertion_results={"results": "请求超时,断言失败"},
                                                           api_variable_results={"results": "请求超时无法提取变量"},
                                                           api_request_results={"results": "请求超时"},
                                                           api_result_id=api_result_id,
                                                           api_test_plan_id=api_task_id,
                                                           api_business_test_name=api_business_test_name,
                                                           api_url=api_url,
                                                           api_header=header_dict,
                                                           api_body=api_parameter_body_dict,
                                                           )
            else:
                # r.encoding = r.apparent_encoding

                if api_assert_type == '':
                    api_error = 0
                    api_successful = 1
                    api_assertion_results = "断言成功"

                elif api_assert_type == 1:
                    r_text = re.sub(r'(\\u[\s\S]{4})', lambda x: x.group(1).encode("utf-8").decode("unicode-escape"),
                                    r.text)
                    r_text_test = "".join(r_text.split())
                    r_text_data = "".join(api_assert_text.split())
                    try:
                        assert r_text_data in r_text_test
                        api_error = 0
                        api_successful = 1
                        api_assertion_results = "断言成功"
                    except Exception as e:
                        logger.error(
                            "断言失败，用例名称是：" + api_test_case_name + "断言内容 %s 与响应结果不匹配，%s" % (
                                api_assert_text, r_text) + str(e))
                        api_assertion_results = "断言失败: 断言内容 %s 与响应结果不匹配，%s" % (
                            api_assert_text, r_text)
                        api_error = 1
                        api_successful = 0
                        pass

                elif api_assert_type == 2:
                    r_text = re.sub(r'(\\u[\s\S]{4})', lambda x: x.group(1).encode("utf-8").decode("unicode-escape"),
                                    r.text)
                    r_text_test = "".join(r_text.split())
                    r_text_data = "".join(api_assert_text.split())
                    try:
                        assert r_text_data == r_text_test
                        api_error = 0
                        api_successful = 1
                        api_assertion_results = "断言成功"
                    except Exception as e:
                        logger.error(
                            "断言失败，用例名称是：" + api_test_case_name + "断言内容 %s 与响应结果不匹配，%s" % (
                                api_assert_text, r_text) + str(e))
                        api_assertion_results = "断言失败: 断言内容 %s 与响应结果不匹配，%s" % (
                            api_assert_text, r_text)
                        api_error = 1
                        api_successful = 0
                        pass
                elif api_assert_type == 3:
                    database = APIDatabase.objects.get(id=database_id)
                    db = HandleDB(database.api_host, int(database.api_port), database.user, database.password,
                                  database.database)

                    count = db.get_count(database_sql)
                    db.close()
                    if str(count) == str(api_assert_text):
                        api_error = 0
                        api_successful = 1
                        api_assertion_results = "断言成功"
                    else:
                        logger.error("断言失败，用例名称是：" + api_test_case_name + '断言失败,查询的数据是： %s' % str(count))
                        api_assertion_results = '断言失败,查询的数据是： %s' % str(count)
                        api_error = 1
                        api_successful = 0
                        pass

                elif api_assert_type == 4:
                    try:
                        assert str(api_assert_text) == str(r.status_code)
                        api_error = 0
                        api_successful = 1
                        api_assertion_results = "断言成功"
                    except Exception as e:
                        logger.error("断言失败，用例名称是：" + api_test_case_name + "断言失败: code状态码 %s 与响应状态码不匹配，%s" % (
                            api_assert_text, str(r.status_code)) + str(e))
                        api_assertion_results = "断言失败: code状态码 %s 与响应状态码不匹配，%s" % (api_assert_text, str(r.status_code))
                        api_error = 1
                        api_successful = 0
                        pass

                if ApiInterfacesParameterExtraction.objects.filter(api_test_case_id=api_test_case_id).count() > 0:
                    ApiInterfacesParameterExtraction.objects.filter(api_test_case_id=api_test_case_id).delete()

                    for api_parameter_extractions in api_parameter_extraction:

                        if api_parameter_extractions['api_value_variable'] == "":
                            pass
                        else:
                            v_text = api_parameter_extractions['api_value_variable'].split(".")
                            # 提取变量
                            try:
                                api_result = json.loads(r.text)
                            except Exception as e:
                                json_loads = "提取变量json.loads(r.text) 失败：" + str(e)
                                logger.error("提取变量json.loads(r.text) 失败：" + str(e))
                                pass
                            try:
                                for a in v_text:
                                    if "[" in a and "]" in a:
                                        variable_1 = a.split('[')[0]
                                        variable_2 = a.split('[')[1].split(']')[0]
                                        if variable_1 == "":
                                            api_result = api_result[0]
                                        else:
                                            api_result = api_result[variable_1][int(variable_2)]
                                    else:
                                        if a == "0":
                                            api_result = api_result[int(a)]
                                        else:
                                            api_result = api_result[a]

                                api_variable_results = str(api_result)
                            except Exception as e:
                                api_variable_results = api_parameter_extractions['api_key_variable']
                                pass

                            logger.info("自定义变量表中有该case_id")

                            ApiInterfacesParameterExtraction.objects.create(api_test_case_id=api_test_case_id,
                                                                            api_variable_results=api_variable_results,
                                                                            api_value_variable=
                                                                            api_parameter_extractions[
                                                                                'api_value_variable'],
                                                                            api_key_variable=api_parameter_extractions[
                                                                                'api_key_variable'])
                else:
                    logger.info("自定义变量表中 无 该 case_id")

                    for api_parameter_extractions in api_parameter_extraction:

                        if api_parameter_extractions['api_key_variable'] == "":
                            pass
                        else:
                            v_text = api_parameter_extractions['api_value_variable'].split(".")
                            # 提取变量
                            try:
                                api_result = json.loads(r.text)
                            except Exception as e:
                                json_loads = "提取变量json.loads(r.text) 失败：" + str(e)
                                logger.error("提取变量json.loads(r.text) 失败：" + str(e))
                                pass
                            try:
                                for a in v_text:
                                    if "[" in a and "]" in a:
                                        variable_1 = a.split('[')[0]
                                        variable_2 = a.split('[')[1].split(']')[0]
                                        api_result = api_result[variable_1][int(variable_2)]
                                    else:
                                        api_result = api_result[a]

                                api_variable_results = str(api_result)
                            except Exception as e:
                                logger.info(str(api_test_case_name) + " 参数提取失败" + api_parameter_extractions[
                                    'api_key_variable'] + str(e))
                                api_variable_results = api_parameter_extractions['api_key_variable']
                                logger.error(api_variable_results)
                                pass

                            if ApiInterfacesParameterExtraction.objects.filter(
                                    api_key_variable=api_parameter_extractions['api_key_variable']).count() > 0:
                                api_parameter_extraction_list = (
                                        str(api_parameter_extractions['api_key_variable']) + "变量名称重复,请重新填写")
                            else:
                                ApiInterfacesParameterExtraction.objects.create(api_test_case_id=api_test_case_id,
                                                                                api_variable_results=
                                                                                api_parameter_extractions[
                                                                                    'api_variable_results'],
                                                                                api_value_variable=api_variable_results,
                                                                                api_key_variable=
                                                                                api_parameter_extractions[
                                                                                    'api_key_variable'])

                api_parameter_extraction = ApiInterfacesParameterExtraction.objects.filter(
                    api_test_case_id=api_test_case_id)

                api_parameter_extraction_list = []
                if api_parameter_extraction.count() > 0:
                    for api_parameter_extractions in api_parameter_extraction:
                        api_parameter_extraction_dict = {
                            "api_key_variable": api_parameter_extractions.api_key_variable,
                            "api_variable_results": api_parameter_extractions.api_variable_results

                        }
                        api_parameter_extraction_list.append(api_parameter_extraction_dict)

                APITestPlanResultAssociated.objects.create(api_test_case_name=api_test_case_name, api_error=api_error,
                                                           api_successful=api_successful, abnormal=abnormal,
                                                           json_extract_variable_conversion=json_loads,
                                                           api_assertion_results=api_assertion_results,
                                                           api_variable_results=str(api_parameter_extraction_list),
                                                           api_request_results=r.json(),
                                                           api_result_id=api_result_id,
                                                           api_test_plan_id=api_task_id,
                                                           api_business_test_name=api_business_test_name,
                                                           api_url=r.url,
                                                           api_body=api_parameter_body_dict,
                                                           api_header=header_dict
                                                           )
        except Exception as e:
            abnormal = str(e)
            if api_assertion_results == "断言成功":
                api_error = 0
                api_successful = 1
                APITestPlanResultAssociated.objects.create(api_test_case_name=api_test_case_name,
                                                           api_error=api_error,
                                                           api_successful=api_successful, abnormal=abnormal,
                                                           json_extract_variable_conversion=json_loads,
                                                           api_assertion_results=api_assertion_results,
                                                           api_variable_results=str(api_parameter_extraction_list),
                                                           api_request_results=r.text.encode().decode("unicode_escape"),
                                                           api_result_id=api_result_id,
                                                           api_test_plan_id=api_task_id,
                                                           api_business_test_name=api_business_test_name,
                                                           api_url=r.url,
                                                           api_header=header_dict,
                                                           api_body=api_parameter_body_dict,
                                                           )
            else:
                api_error = 1
                api_successful = 0
                APITestPlanResultAssociated.objects.create(api_test_case_name=api_test_case_name, api_error=api_error,
                                                           api_successful=api_successful, abnormal=abnormal,
                                                           json_extract_variable_conversion=json_loads,
                                                           api_assertion_results=api_assertion_results,
                                                           api_variable_results=str(api_parameter_extraction_list),
                                                           api_request_results=r.text.encode().decode("unicode_escape"),
                                                           api_result_id=api_result_id,
                                                           api_test_plan_id=api_task_id,
                                                           api_business_test_name=api_business_test_name,
                                                           api_url=api_url,
                                                           api_header=header_dict,
                                                           api_body=api_parameter_body_dict,
                                                           )
        continue
