# -*- coding: utf-8 -*-

from django.views.generic import View
import json
import traceback
from automated_main.utils.http_format import response_success, response_failed
from django.http import response
from automated_main.exception.my_exception import MyException
# from automated_main.models.api_automation.api_business_test import ApiBusinessTest, ApiBusinessTestAssociated
# from automated_main.form.api_business_test import ApiBusinessTestForm
from automated_main.models.api_querrydiff.record_opt import DbRecordOpt
from automated_main.utils.api_utils import querry_diff
from automated_main.utils.es_utils import es_search


import logging

logger = logging.getLogger('django')


class ApiQuerydiffTaskView(View):

    def get(self, request, task_id, *args, **kwargs):
        """
        获取单个任务详情
        :param request:
        :param args:
        :param kwargs:
        :return:
        """

        db = DbRecordOpt()
        task_info = db.querry_excute("select * from automated_main_querrydifftask where id={}".format(task_id))

        return response_success(task_info)

    def delete(self, request, task_id, *args, **kwargs):
        """
        删除任务
        :param request:
        :param args:
        :param kwargs:
        :return:
        """

        db = DbRecordOpt()
        r = db.querry_excute("select * from automated_main_querrydifftask where id={} and status = 1".format(task_id))
        if len(r) > 0:
            return response_failed(1, "执行中，无法删除")
        try:
            db.write_excute("delete from automated_main_querrydifftask where id={} and status != 1".format(task_id))
            db.write_excute("delete from automated_main_querrydifftaskitems where task_id={}".format(task_id))

        except:
            print(traceback.print_exc())
            return response_failed(1, '删除失败')
        return response_success()

    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)

        update_sql = 'update automated_main_querrydifftask set task_name={},source_env_id={},target_env_id={},log_time={},project_id={},simple_num={},urls={},opt_num={} where id={}'

        db = DbRecordOpt()
        try:
            db.querry_excute(update_sql.format(data['task'],data['source'],data['target'],data['log_time'],data['project'],data['num'],data['urls'],data['opt_num']))
        except:
            logger.error('任务更新失败，req:{}', data)
            response_failed(1, '任务更新失败')


        return response_success(data)

    def put(self, request, *args, **kwargs):
        """
        创建任务
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        body = request.body
        if not body:
            return response_success()
        # {'submitName': '112', 'ownerProjectId': 9, 'sourceEnv': 12, 'targetEnv': 'SCRM-开发环境', 'logTime': '2022-07-24', 'subUrl': 'asdf,2323', 'createUserName': 'chentaolian'}
        data = json.loads(body)
        add_sql = 'insert into automated_main_querrydifftask (`task_name`, `source_env_id`, `target_env_id`, `log_time`, ' \
                  '`project_id`, `simple_num`, `urls`, `opt_num`, `status`, `es_select_status`,`api_count`,`error_count` `created_name`) values (' \
                  ':submitName,:sourceEnv,:targetEnv,:logTime,:ownerProjectId,:simple,:subUrl,0,0,0,0,0,:createUserName)'

        db = DbRecordOpt()
        db.batch(add_sql, (data))

        return response_success()


class ApiQuerydiffTaskActionView(View):
    def post(self, request, *args, **kwargs):
        """
        执行es筛选
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        logger.info("执行es筛选")
        body = request.body
        if not body:
            return response.HttpResponseBadRequest
        data = json.loads(body)
        task_id = data.get('task_id', '')
        db = DbRecordOpt()
        task = db.querry_excute('select qt.id,qt.opt_num,qt.status,ae.api_title as source_url,qt.log_time,qt.urls,qt.project_id  from automated_main_querrydifftask qt LEFT JOIN automated_main_apienvironment ae on qt.source_env_id=ae.id  where qt.id={} and qt.es_select_status=0 and qt.status = 0'.format(int(task_id)))
        if len(task) < 1:
            return response_failed(1, "当前任务已经筛选完成且已经有运行记录，不能再次筛选，请重新新建任务")

        db.write_excute('delete from automated_main_querrydifftaskitems where task_id = {}'.format(task_id))
        logger.info("删除case成功")

        order = {
            "size": 0,
            "query": {
                "wildcard": {
                    "apiPath": "http://datacenter.qk.com/*"
                }
            },
            "aggs": {
                "group_url": {
                    "terms": {
                        "field": "apiPath"
                    },
                "aggs": {
                    "group_param": {
                        "terms": {
                            "field": "request",
                            "size": 100
                        }
                    }
                }
                }

            }
        }
        if len(task[0].get('urls', '')) > 0:
            url_list = task[0].get('urls').split(',')
            urls = db.querry_excute("select apc.api_url as api_url, apc.api_method from automated_main_apitestcase apc LEFT JOIN automated_main_apimodule am on am.id=apc.api_module_id LEFT JOIN automated_main_apiproject ap on ap.id=am.api_project_id where ap.id = {} and apc.api_url in ({})".format(int(task[0].get('project_id'))), "'" + "','".join(url_list) + "'")

        else:
            urls = db.querry_excute('select apc.api_url as api_url, apc.api_method from automated_main_apitestcase apc LEFT JOIN automated_main_apimodule am on am.id=apc.api_module_id LEFT JOIN automated_main_apiproject ap on ap.id=am.api_project_id where ap.id = {} and apc.api_url !=""'.format(int(task[0].get('project_id'))))

        logger.info("执行任务id: %s ,es筛选", task_id)
        es_index = 'data_center_log.api-log-' + task[0].get('log_time').replace('-', '.')
        api_count = 0
        for url in urls:
            batch_sql = []
            order['query']['wildcard']['apiPath'] = task[0].get('source_url', 'http://datacenter.qk.com') + url['api_url']
            order['aggs']['group_url']['aggs']['group_param']['terms']['size'] = int(task[0].get('opt_num'))
            es_result = es_search(order, es_index)

            try:
                es_result = es_result['aggregations']['group_url']['buckets'][0]['group_param']['buckets']
            except:
                es_result = []

            for x in es_result:

                batch_sql.append({'task': task_id, 'method': url['method'], 'url': url['api_url'], 'param': x.get('key', ''), 'num': x.get('doc_count', 0)})

            if len(batch_sql) > 0:
                db.batch('insert automated_main_querrydifftaskitems (`task_id`, `api_url`, `param`,`method`, `req_count`, `result`, `status`) values(:task, :url, :param, :method , :num, null,0)', batch_sql)

            api_count = api_count + len(es_result)

        db.querry_excute('update automated_main_querrydifftask set es_select_status=1,api_count={}'.format(api_count))
        return response_success()

    def get(self, request, task_id, *args, **kwargs):
        """
        运行任务
        :param request:
        :param args:
        :param kwargs:
        :return:
        """
        if task_id == '':
            return response.HttpResponseBadRequest()
        db = DbRecordOpt()
        t = 'select qt.id,qt.task_name,qt.opt_num,qt.status,ae.api_title as source_url, aet.api_title as target_url from automated_main_querrydifftask qt LEFT JOIN automated_main_apienvironment ae on qt.source_env_id=ae.id LEFT JOIN automated_main_apienvironment aet on aet.id=qt.target_env_id where qt.id={}'.format(
            task_id)
        task = db.querry_excute(t)
        if len(task) < 1:
            return response.Http404()

        if task[0].get('source_url', '') == '' or task[0].get('target_url', '') == '':
            return response_failed(1, "请完善环境的url")

        if task[0].get('status') == 1:
            return response_failed(1, '任务运行中')

        api_sql = 'select id,api_url,param,method,result from automated_main_querrydifftaskitems where task_id={}'.format(
            task_id)

        api_list = db.querry_excute(api_sql)
        if len(api_list) < 1:
            return response_failed(1, '接口数据为空，请筛选后再运行')

        db.write_excute('update automated_main_querrydifftask set status=1 where id={}'.format(task_id))
        db.write_excute('update automated_main_querrydifftaskitems set result=null where task_id={}'.format(task_id))

        for i in api_list:
            up_api = "update automated_main_querrydifftaskitems set result='{}',status={} where id={}"
            logger.info("[task-run]执行任务 %s, 接口: %s", task[0]['task_name'], i['api_url'])

            diff = {"result": "执行请求异常", "status": 2}
            try:
                diff = querry_diff(task[0], i)
            except:
                logger.error("执行请求异常，请检查")

            db.write_excute(up_api.format(diff.get('result'), diff.get('status'), i.get('id')))
        err = db.querry_excute("select count(1) as t from automated_main_querrydifftaskitems where status=2 and task_id={}".format(task_id))

        db.write_excute(
            'update automated_main_querrydifftask set status=2,opt_num=opt_num+1,error_counter={} where id={}'.format(err[0]['t'], task_id))

        logger.info("[task-end]任务执行完毕！错误用例数：%d", err[0]['t'])
        return response_success()


class ApiQuerydiffTaskListView(View):

    def get(self, request, *args, **kwargs):
        """
        获取任务列表
        :param request:
        :param args:
        :param kwargs:
        :return:
        """


        ## url参数取值 {'taskName': ['1'], 'size': ['10'], 'page': ['1']}
        # body取值，{"taskName":"","size":}
        # 获取url后的参数
        param = dict(request.GET)

        list_sql = "select qdt.*,apj.api_project_name as project_name,aer.api_title as source, aert.api_title as target from automated_main_querrydifftask qdt left join automated_main_apiproject apj on apj.id=qdt.project_id left join automated_main_apienvironment aer on aer.id=qdt.source_env_id left join automated_main_apienvironment aert on aert.id=qdt.target_env_id  where 1=1"
        if len(param.get('taskName', list())) > 0:
            list_sql = list_sql + " and qdt.task_name like '%{}%'".format(param.get('taskName')[0])

        list_sql = list_sql + " order by id desc"
        db = DbRecordOpt()
        total = db.querry_excute(list_sql)
        p_size = int(param.get('size')[0]) if len(param.get('size', list())) > 0 else 10
        p_num = int(param.get('page')[0]) if len(param.get('page', list())) > 0 else 1

        list_sql = list_sql + " limit {} offset {}".format(p_size, p_size * (p_num - 1))

        task_list = db.querry_excute(list_sql)

        return response_success({'task': task_list, 'total': len(total)})

