# -*- coding: utf-8 -*-
# @Time : 2022/7/21 14:46
# @Author : wangyinghao
# @Site : 
# @File : api_test_plan_view.py
# @Software: PyCharm
from django.views.generic import View
import json
from datetime import datetime
from django.forms import model_to_dict
from automated_main.utils.http_format import response_success, response_failed
from automated_main.exception.my_exception import MyException
from automated_main.models.api_automation.api_test_plan import ApiTestPlan, APITestPlanResult, APITestPlanResultAssociated
from automated_main.models.api_automation.api_scenarios_case import ApiScenariosCase
from automated_main.form.api_test_plan import ApiTestPlanForm
from automated_main.models.api_automation.api_management import ApiManagement
from automated_main.view.api_automation.api_test_plan.extend.test_plan_thread import TaskThread

from django.core.paginator import Paginator
import arrow
import logging

logger = logging.getLogger('django')


class APITestPlanSuspended(View):

    def post(self, request, *args, **kwargs):
        """
        暂停接口计划
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        body = request.body
        if not body:
            return response_success()
        data = json.loads(body)
        api_task = ApiTestPlan.objects.get(id=data["api_test_plan_id"])
        api_task.status = 2
        api_task.save()

        return response_success("暂停API测试计划成功")


class ApiTestPlanView(View):

    def get(self, request, api_test_plan_id, *args, **kwargs):
        """
        获取单个API测试计划
        :param request:
        :param api_test_plan_id: API测试计划ID
        :param args:
        :param kwargs:
        :return:
        """
        api_test_plan = ApiTestPlan.objects.get(id=api_test_plan_id)
        return response_success(model_to_dict(api_test_plan))

    def delete(self, request, api_test_plan_id, *args, **kwargs):
        """
        删除API测试计划
        :param request:
        :param api_test_plan_id:任务ID
        :param args:
        :param kwargs:
        :return:
        """
        ApiTestPlan.objects.get(id=api_test_plan_id).delete()

        return response_success("删除API测试计划成功")

    def put(self, request, *args, **kwargs):
        """
        创建API测试任务
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        body = request.body
        if not body:
            return response_success()
        data = json.loads(body)

        form = ApiTestPlanForm(data)
        if form.is_valid():
            if data['api_test_plan_id'] == 0:
                ApiTestPlan.objects.create(**form.cleaned_data)
                return response_success("创建API测试任务成功")
        else:
            raise MyException()

    def post(self, request, api_test_plan_id, *args, **kwargs):
        """
        更改API测试计划
        :param request:
        :param api_test_plan_id: API测试任务ID
        :param args:
        :param kwargs:
        :return:
        """
        body = request.body
        if not body:
            return response_success()
        data = json.loads(body)
        form = ApiTestPlanForm(data)
        if form.is_valid():
            api_test_plan = ApiTestPlan.objects.get(id=api_test_plan_id)
            api_test_plan.api_test_plan_name = data['api_test_plan_name']
            api_test_plan.api_test_plan_describe = data['api_test_plan_describe']
            api_test_plan.cases = data['cases']
            api_test_plan.api_management_id = data['api_management_id']
            api_test_plan.api_send_email = data['api_send_email']
            api_test_plan.api_send_enterprise_wechat = data['api_send_enterprise_wechat']
            api_test_plan.api_environment_id = data['api_environment_id']
            api_test_plan.database_id = data['database_id']
            api_test_plan.time_interval_seconds = data['time_interval_seconds']
            api_test_plan.time_interval_hours = data['time_interval_hours']
            api_test_plan.time_interval_minutes = data['time_interval_minutes']
            api_test_plan.time_interval_day = data['time_interval_day']
            api_test_plan.end_time = data['end_time']
            api_test_plan.starting_time = data['starting_time']
            api_test_plan.timing_task_status = data['timing_task_status']
            api_test_plan.update_time = datetime.now()
            api_test_plan.save()

            return response_success("编辑API测试计划成功")
        else:
            raise MyException()


class GetScenariosCaseTree(View):

    def get(self, request, api_management_id, *args, **kwargs):
        """
        获取Api测试用例树形结构
        :param request:
        :param api_management_id:
        :param args:
        :param kwargs:
        :return:
        """
        api_management_data = ApiManagement.objects.filter(id=api_management_id)

        data_list = []
        for api_management in api_management_data:
            api_management_dict = {
                "api_project_name": api_management.name,
                "isParent": True
            }
            api_scenarios_case_list = []

            api_scenarios_case_data = ApiScenariosCase.objects.filter(api_management_id=api_management_id)
            for api_scenarios_case in api_scenarios_case_data:
                api_case_dict = {
                    "api_scenarios_case_name": api_scenarios_case.api_scenarios_case_name,
                    "isParent": False,
                    "api_scenarios_case_id": api_scenarios_case.id
                }
                api_scenarios_case_list.append(api_case_dict)

            api_management_dict["children"] = api_scenarios_case_list
            data_list.append(api_management_dict)
        return response_success(data_list)


class PerformApiPlan(View):

    def post(self, request, api_test_plan_id, *args, **kwargs):
        """
        执行当前API测试计划
        :param request:
        :param api_test_plan_id:
        :param args:
        :param kwargs:
        :return:
        """

        if api_test_plan_id == "":
            return response_failed({"status": 10200, "message": "api_test_plan_id is null"})

        # 1.在执行线程之前，判断当前任务是否在执行
        api_tasks = ApiTestPlan.objects.get(id=api_test_plan_id)
        if api_tasks.status == 1:
            return response_failed({"status": 10200, "message": "当前该测试任务正在执行！"})
        else:
            # 2. 修改任务的状态为：1-执行中
            api_tasks = ApiTestPlan.objects.get(id=api_test_plan_id)
            api_tasks.status = 1
            api_tasks.save()
            # 通过多线程运行测试任务
            TaskThread(api_test_plan_id).run()
            return response_success({"status": 10200, "message": "任务开始执行！"})

    def get(self, request, *args, **kwargs):
        """
        执行所有API测试计划
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        api_test_plan = ApiTestPlan.objects.filter(timing_task_status="true")
        for plan in api_test_plan:

            # 1.在执行线程之前，判断当前有没有任务在执行
            api_tasks = ApiTestPlan.objects.get(id=plan.id)
            if api_tasks.status == 1:
                logger.info("该任务正在执行中：" + plan.api_test_task_name)
                continue
            else:
                # 2. 修改任务的状态为：1-执行中
                api_plan = ApiTestPlan.objects.get(id=plan.id)
                api_plan.status = 1
                api_plan.save()
                # 通过多线程运行测试任务
                TaskThread(plan.id).run()
        return response_success({"status": 10200, "message": "测试计划开始执行！"})


class CheckApiPlanResultList(View):

    def get(self, request, api_test_plan_id, size_page, page, *args, **kwargs):
        """
        查看API测试计划报告列表
        :param page:
        :param size_page:
        :param request:
        :param api_test_plan_id:
        :param args:
        :param kwargs:
        :return:
        """
        if api_test_plan_id == "":
            return response_failed({"status": 10102, "message": "api_test_task_id不能为空"})
        result_data = APITestPlanResult.objects.filter(api_test_plan_id=api_test_plan_id).order_by('-create_time')
        data = []
        for i in result_data:
            result = {
                "id": i.id,
                "api_test_result_name": i.api_test_result_name,
                "create_time": i.create_time,
                "api_error_total_number": i.api_error_total_number,
                "api_successful_total_number": i.api_successful_total_number,
                "api_total_number": i.api_total_number

            }
            data.append(result)
        api_result_total = len(data)
        p = Paginator(data, size_page)

        if int(page) > int(p.num_pages):
            page1 = p.page(p.num_pages)
            current_page = page1.object_list
        else:
            page1 = p.page(page)
            current_page = page1.object_list
        return response_success({'status': 10102, 'data': current_page, 'api_result_total': api_result_total})


class CheckApiResult(View):
    def get(self, request, api_test_result_id, size_page, page, *args, **kwargs):
        """
        查看任务--测试报告列表--测试结果列表
        :param size_page: 展示条数
        :param page: 页数
        :param request:
        :param api_test_result_id:
        :param args:
        :param kwargs:
        :return:
        """
        if api_test_result_id == "":
            return response_failed({"status": 10102, "message": "api_test_task_id不能为空"})
        r = APITestPlanResultAssociated.objects.filter(api_result_id=api_test_result_id)

        data = []
        for i in r:
            result = {
                "id": i.id,
                "api_test_case_name": i.api_test_case_name,
                "api_task_name": i.api_test_plan.api_test_plan_name,
                "api_business_test_name": i.api_business_test_name,
                "api_error": i.api_error,
                "api_successful": i.api_successful,
                "abnormal": i.abnormal,
                "json_extract_variable_conversion": i.json_extract_variable_conversion,
                "api_assertion_results": i.api_assertion_results,
                "api_request_results": i.api_request_results,
                "api_result_id": i.api_result_id,
                "api_task_id": i.api_test_plan_id,
                "create_time": arrow.get(str(i.create_time)).format('YYYY-MM-DD HH:mm:ss'),
            }
            data.append(result)
        p = Paginator(data, size_page)
        if int(page) > int(p.num_pages):
            page1 = p.page(p.num_pages)
            current_page = page1.object_list
        else:
            page1 = p.page(page)
            current_page = page1.object_list

        api_result = APITestPlanResult.objects.get(id=api_test_result_id)

        case_result_total = [int(api_result.api_successful_total_number), int(api_result.api_error_total_number)]

        return response_success({'status': 10102, 'data': current_page, "case_result_total": case_result_total})

    def post(self, request, api_test_case_result_id, *args, **kwargs):
        """
        查看任务--测试报告列表--测试结果列表--单独测试用例报告
        :param request:
        :param api_test_case_result_id:API测试结果关联表的ID
        :param args:
        :param kwargs:
        :return:
        """
        if api_test_case_result_id == "":
            return response_failed({"status": 10102, "message": "api_test_case_result_id不能为空"})
        r = APITestPlanResultAssociated.objects.filter(id=api_test_case_result_id)
        data = []
        for i in r:
            result = {
                "id": i.id,
                "api_test_case_name": i.api_test_case_name,
                "api_task_name": i.api_test_plan.api_test_plan_name,
                "api_business_test_name": i.api_business_test_name,
                "api_error": i.api_error,
                "api_successful": i.api_successful,
                "abnormal": i.abnormal,
                "json_extract_variable_conversion": i.json_extract_variable_conversion,
                "api_assertion_results": i.api_assertion_results,
                "api_request_results": i.api_request_results,
                "api_result_id": i.api_result_id,
                "api_task_id": i.api_test_plan_id,
                "create_time": i.create_time,
                "api_variable_results": i.api_variable_results,
                "api_header": i.api_header,
                "api_url": i.api_url,
                "api_body": i.api_body
            }

            data.append(result)
        return response_success({'status': 10102, 'data': data})

    def delete(self, request, api_test_result_id, *args, **kwargs):
        """
        查看任务--测试报告列表--删除测试报告
        :param request:
        :param api_test_result_id:API测试结果关联表的ID
        :param args:
        :param kwargs:
        :return:
        """
        if api_test_result_id == "":
            return response_failed({"status": 10102, "message": "api_test_result_id不能为空"})
        APITestPlanResult.objects.get(id=api_test_result_id).delete()

        return response_success("删除测试报告成功")


class CheckApiResultErrorList(View):
    def get(self, request, api_test_result_id, size_page, page, *args, **kwargs):
        """
        查看任务--测试报告列表--测试结果列表
        :param size_page: 展示条数
        :param page: 页数
        :param request:
        :param api_test_result_id:
        :param args:
        :param kwargs:
        :return:
        """
        if api_test_result_id == "":
            return response_failed({"status": 10102, "message": "api_test_task_id不能为空"})
        r = APITestPlanResultAssociated.objects.filter(api_result_id=api_test_result_id, api_error=1)
        data = []
        for i in r:
            result = {
                "id": i.id,
                "api_test_case_name": i.api_test_case_name,
                "api_task_name": i.api_test_plan.api_test_plan_name,
                "api_business_test_name": i.api_business_test_name,
                "api_error": i.api_error,
                "api_successful": i.api_successful,
                "abnormal": i.abnormal,
                "json_extract_variable_conversion": i.json_extract_variable_conversion,
                "api_assertion_results": i.api_assertion_results,
                "api_request_results": i.api_request_results,
                "api_result_id": i.api_result_id,
                "api_task_id": i.api_test_plan_id,
                "create_time": arrow.get(str(i.create_time)).format('YYYY-MM-DD HH:mm:ss')
            }
            data.append(result)
        p = Paginator(data, size_page)

        if int(page) > int(p.num_pages):
            page1 = p.page(p.num_pages)
            current_page = page1.object_list
        else:
            page1 = p.page(page)
            current_page = page1.object_list
        api_result = APITestPlanResult.objects.get(id=api_test_result_id)

        case_result_total = [int(api_result.api_successful_total_number), int(api_result.api_error_total_number)]
        return response_success({'status': 10102, 'data': current_page, "case_result_total": case_result_total})