# -*- coding: utf-8 -*-
# @Time : 2021/11/25 19:56
# @Author : wangyinghao
# @Site :
# @File : new_run_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_test_case import ApiParameterExtraction
from automated_main.models.api_automation.api_test_task import APITestResultAssociated
from automated_main.models.api_automation.api_environment import APIGlobalVariable
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 ExtractParameters
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_task/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_business_test_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")

            if api_headers == "{}" or "":
                header_dict = {}
            else:
                api_headers = RegularMatch(api_headers, api_environment_id, "1")

                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")
                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")
                data_payload = ast.literal_eval(parameter_data_task)

            r = InterfaceRequest(str(api_method), str(api_parameter_types), api_url, header_dict,
                                 api_parameter_body_dict, data_payload)
            if r == "请求超时":
                api_error = 1
                api_successful = 0
                APITestResultAssociated.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_task_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:
                if api_assert_type == '':
                    api_error = 0
                    api_successful = 1
                    api_assertion_results = "断言成功"

                elif api_assert_type == 1:
                    try:
                        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())

                        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

                try:
                    response_message = r.json()
                except json.decoder.JSONDecodeError:
                    api_error = 1
                    api_successful = 0
                    APITestResultAssociated.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="",
                                                           api_request_results={"result": "接口返回结果类型错误非JSON格式"},
                                                           api_result_id=api_result_id,
                                                           api_task_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

                if ApiParameterExtraction.objects.filter(api_test_case_id=api_test_case_id).count() > 0:
                    ApiParameterExtraction.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

                            ApiParameterExtraction.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:

                    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 ApiParameterExtraction.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:
                                ApiParameterExtraction.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 = ApiParameterExtraction.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)

                APITestResultAssociated.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_task_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
                APITestResultAssociated.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_task_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:
                try:
                    result = r.json()
                except Exception as e:
                    result = r.text
                    pass

                api_error = 1
                api_successful = 0
                APITestResultAssociated.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=result,
                                                       api_result_id=api_result_id,
                                                       api_task_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
