# -*- coding: utf-8 -*-
# @Time : 2022/3/31 10:45
# @Author : wangyinghao
# @Site : 
# @File : new_performance_task_thread.py
# @Software: PyCharm
import os
import random
import threading
import django

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "AutomatedTestPlatform.settings")
django.setup()
from time import sleep
from automated_main.models.performance_test.performance_script import PerformanceScript
from automated_main.models.performance_test.performance_report import PerformanceReport, PerformanceReportError
from AutomatedTestPlatform import settings
import time
import logging
from pathlib import Path
from django.db.models import Q
from automated_main.utils.jmeter_perform import create_para_jmx
import logging
import csv
import pandas as pd
import numpy as np
from functools import reduce

BASE_PATH = settings.BASE_DIR.replace("\\", "/")
EXTEND_DIR = BASE_PATH + "/automated_main/view/performance_test/performance_script/extend/"
logger = logging.getLogger('django')


class NewTaskThread:

    def __init__(self, task_id, get_host):
        self.tid = task_id
        self.host = get_host

    def run_cases(self):

        performance_script = PerformanceScript.objects.get(id=self.tid)
        performance_script_path = settings.JMETER_ROOT + "/" + os.path.basename(
            performance_script.performance_script)
        logger.info("脚本路径" + performance_script_path)
        fn = time.strftime("%Y-%m-%d-%H-%M-%S", time.localtime())
        fn = str(performance_script.id) + "-" + fn + '-%d' % random.randint(0, 100)

        logger.info("性能脚本名称" + fn)

        # ENV_PROFILE = os.getenv("ENV")
        # if ENV_PROFILE == "SERVER":
        #     jmeter = 'jmeter'
        # elif ENV_PROFILE == "1":
        #     jmeter = 'jmeter'
        # else:
        #     jmeter = 'jmeter'
        jmx = create_para_jmx(performance_script_path, performance_script.performance_threads,
                              performance_script.performance_loop_count,
                              str(performance_script.performance_duration),
                              performance_script.performance_ramp_up_time_seconds,
                              performance_script.performance_scheduler,
                              performance_script.loop_count_forever,
                              performance_script.data_set, performance_script.performance_data_script)
        jmeter_script = 'jmeter -n -t ' + jmx + ' -l ' + settings.JMETER_REPORT + '/' + fn + '/' + fn + '.jtl'
        logger.info("性能脚本命令：" + jmeter_script)
        ENV_PROFILE = os.getenv("ENV")
        logger.info(ENV_PROFILE)

        os.system(jmeter_script)

        if ENV_PROFILE == "SERVER":
            CMDRUNNER = '$CMDRUNNER'
        elif ENV_PROFILE == "1":
            CMDRUNNER = os.getenv('CmdRunner')
        else:
            CMDRUNNER = '$CMDRUNNER'

        jmeter_aggregate_report_csv = settings.JMETER_REPORT + '/' + fn + '/' + fn + '-aggregate' + '.csv'

        print(jmeter_aggregate_report_csv)

        response_codes_per_second_csv = settings.JMETER_REPORT + '/' + fn + '/' + fn + '-response_codes_per_second' + '.csv'

        # 聚合报告
        jmeter_aggregate_report = 'java -jar ' + CMDRUNNER + ' --tool Reporter --generate-csv ' + jmeter_aggregate_report_csv + ' --input-jtl ' + settings.JMETER_REPORT + "/" + fn + "/" + fn + ".jtl" + ' --plugin-type AggregateReport'
        logger.info("***********")
        logger.info(jmeter_aggregate_report)
        logger.info("***********")

        # 响应时间随时间变化曲线
        response_codes_per_second_report = 'java -jar ' + CMDRUNNER + ' --tool Reporter --generate-csv ' + response_codes_per_second_csv + ' --input-jtl ' + settings.JMETER_REPORT + "/" + fn + "/" + fn + ".jtl" + ' --plugin-type ResponseTimesOverTime'

        os.system(response_codes_per_second_report)
        os.system(jmeter_aggregate_report)

        if performance_script.loop_count_forever == 'true':
            pressure_test_content = (
                    '每秒执行' + performance_script.performance_threads + "线程, 持续时间：" + performance_script.performance_duration + "秒")
        else:
            pressure_test_content = ('每秒执行' + performance_script.performance_threads + "线程")

        performance_report = PerformanceReport.objects.create(performance_report_name=fn,
                                                              performance_script_id=self.tid,
                                                              pressure_test_content=pressure_test_content)
        performance_report.save()

        # 解析jtl异常问题
        df = pd.read_csv(settings.JMETER_REPORT + '/' + fn + '/' + fn + '.jtl')
        df_1 = pd.DataFrame(df, columns=["label", "responseCode", "responseMessage"])

        df_2 = df_1

        df_2.drop_duplicates(subset=["label", "responseCode", "responseMessage"], keep="first", inplace=True)
        df_3 = df_2.values.tolist()
        jtl_list = []
        jtl_error = ""
        for i in range(len(df_3)):
            jtl_dict = {
                "error": str(df_3[i][0]) + " " + str(df_3[i][1]) + " " + str(df_3[i][2]),
                "code": str(df_3[i][1])
            }
            jtl_list.append(jtl_dict)
        jtl_error_list = []
        for jtl_error in jtl_list:
            if jtl_error["code"] != str("200"):
                j_dict = {
                    "jtl_error": jtl_error["error"]
                }

                jtl_error_list.append(j_dict)
                run_function = lambda x, y: x if y in x else x + [y]
                jtl_error = reduce(run_function, [[], ] + jtl_error_list)

            else:
                j_dict = {
                    "jtl_error": ""
                }

                jtl_error_list.append(j_dict)
                run_function = lambda x, y: x if y in x else x + [y]
                jtl_error = reduce(run_function, [[], ] + jtl_error_list)

        for jtl_error_data in jtl_error:
            PerformanceReportError.objects.create(performance_report_error_name=jtl_error_data['jtl_error'],
                                                  performance_report_id=performance_report.id)

        # # 解析jtl异常问题
        # df = pd.read_csv(settings.JMETER_REPORT + '/' + fn + '/' + fn + '.jtl')
        # jtl_error_list = []
        # for jtl in df.values.tolist():
        #     if jtl[3] != 200:
        #         jtl_error_dict = {
        #             "jtl_error": str(jtl[2]) + " " + str(jtl[3]) + jtl[4]
        #         }
        #         jtl_error_list.append(jtl_error_dict)
        #         run_function = lambda x, y: x if y in x else x + [y]
        #         jtl_error = reduce(run_function, [[], ] + jtl_error_list)
        #
        #     else:
        #         jtl_error_dict = {
        #             "jtl_error": ""
        #         }
        #         jtl_error_list.append(jtl_error_dict)
        #         run_function = lambda x, y: x if y in x else x + [y]
        #         jtl_error = reduce(run_function, [[], ] + jtl_error_list)
        #
        # for jtlerror_data in jtl_error:
        #     PerformanceReportError.objects.create(performance_report_error_name=jtlerror_data['jtl_error'], performance_report_id=performance_report.id)

        performance_script.performance_status = 2
        performance_script.save()

    def run_tasks(self):
        logger.info("创建性能线程任务...")
        sleep(2)
        threads = []
        t1 = threading.Thread(target=self.run_cases)
        threads.append(t1)

        for t in threads:
            t.start()

        for t in threads:
            t.join()

    def run(self):
        threads = []
        t = threading.Thread(target=self.run_tasks)
        threads.append(t)

        for t in threads:
            t.start()


if __name__ == '__main__':
    logger.info("开始")
    # run()  # 丢给线程去运行任务
    NewTaskThread(16).run()
    logger.info("结束")
