import base64
import copy
import hashlib
import math
import random
import shutil
import zipfile
from os.path import exists
import fire
from Crypto.Cipher import AES
from faker import Faker
from requests import request, Response
import json
from urllib.parse import urljoin
import os
import time

fake = Faker('zh_CN')

interval = 10

# header
header = {
    "Content-Type": "application/json",
}


# Environment Path
class EnvPath:
    token = "TOKEN"


class Prefix:
    UserServer = "api-user"
    CaseServer = "api-case"
    AssetServer = "api-asset"
    TaskServer = "api-task"


# token
_token = os.environ.get(EnvPath.token)

"""  初始化配置相关接口  """
accept_url = Prefix.UserServer + "/users/agreement"  # 接受协议
init_config_url = Prefix.TaskServer + "/system/initConfig"  # 初始化配置
init_serve_url = Prefix.TaskServer + "/system/initServices"  # 初始化服务
conn_master_url = Prefix.TaskServer + "/system/connectMaster"  # 连接master
start_serve_url = Prefix.TaskServer + "/system/start"  # 启动服务

"""  多车增加节点  """
add_worker_url = Prefix.TaskServer + "/worker"  # 增加节点

"""  登录相关接口  """
user_check_url = Prefix.UserServer + "/users/check"
health = Prefix.UserServer + "/health"  # 检查服务是否正常
cloud_login_url = Prefix.UserServer + "/users/login"  # 云端登录
standalone_login_url = Prefix.UserServer + "/users/standalone"  # 单机版登录
login_check = Prefix.UserServer + "/users/check"  # user check

"""  案例库目录相关接口  """
categories_url = Prefix.CaseServer + "/categories"  # 案例库目录
get_categories_url = Prefix.CaseServer + "/categories?withCases=false"  # 获取所有案例库
get_cases_url = "api-case/cases?page=1&filter={category}&pageSize=100"
get_cases_url = Prefix.CaseServer + "/cases?page={page}&filter={category}&pageSize=100"  # 获取当前案例库的所有案例
delete_categories_url = Prefix.CaseServer + "/categories/{}"  # 删除案例库目录

"""  上传文件相关接口  """
file_md5_url = Prefix.AssetServer + "/files/{}?raw={}"  # 验证文件MD5
upload_file_url = Prefix.AssetServer + "/files/{}/upload?raw={}"  # 上传文件

"""  测试案例相关接口  """
case_import_url = Prefix.AssetServer + "/cases/import"  # 导入案例
case_details_url = Prefix.CaseServer + "/cases/{case_id}/data"  # 案例详情
delete_case_url = Prefix.CaseServer + "/trash"  # 删除案例
convert_replay_case_url = Prefix.TaskServer + "/tasks/{id}/convert2case"  # 转换回放案例

"""  测试任务相关接口  """
create_task_url = Prefix.TaskServer + "/tasks"  # 创建task
stop_task_url = Prefix.TaskServer + "/tasks/stop"  # 停止task
stop_sessions_url = Prefix.TaskServer + "/sessions/stop"  # 会话停止
delete_task_url = Prefix.TaskServer + "/tasks/delete"  # 删除task
delete_sessions_url = Prefix.TaskServer + "/sessions/delete"  # 删除停止
result_url = Prefix.TaskServer + "/tasks/task?taskIds={task_id}"  # 删除停止  案例运行结果详情
pause_task_url = Prefix.TaskServer + "/sessions/{task_id}/pause"  # 任务暂停
resume_task_url = Prefix.TaskServer + "/sessions/{task_id}/resume"  # 任务暂停后开始
task_result_url = Prefix.TaskServer + "/tasks/task?taskIds={id}"  # 删除停止  案例运行结果详情

"""  主车相关接口  """
import_vehicle_url = Prefix.AssetServer + "/vehicles/import"  # 导入主车
delete_vehicle_url = Prefix.AssetServer + "/vehicles/{vehicles_id}"  # 删除主车
get_vehicle_url = Prefix.AssetServer + "/vehicles"  # 获取主车信息

"""  地图相关接口  """
import_map_url = Prefix.AssetServer + "/maps"  # 导入地图
delete_map_url = Prefix.CaseServer + "/maps/trash"  # 删除地图
get_map_url = Prefix.CaseServer + "/maps?pageSize=100"  # 获取地图相关信息
road_service_url = Prefix.TaskServer + "/sce"  # 启动路网服务
laneTypeIfInside_url = Prefix.TaskServer + "/sce/{map_id}/location/laneTypeIfInside"  # 监测点是否在车道内

"""  数据驱动相关接口  """
import_data_driven_url = Prefix.AssetServer + "/dd"  # 导入数据驱动源
delete_data_dirven_url = Prefix.AssetServer + "/dd/{id}"  # 删除数据驱动源

""" 资源相关接口 """
import_asset_url = Prefix.AssetServer + "/assets"  # 资源导入
asset_repeat_url = Prefix.AssetServer + "/assets/isrepeat"  # 资源查重
get_asset_url = Prefix.AssetServer + "/assets?schema={}"  # 获取资源信息
delete_asset_url = Prefix.AssetServer + "/assets/{}"  # 删除对应资源

"""  案例导出相关  """
export_case_url = Prefix.AssetServer + "/cases/export"  # 案例导出
download_case_url = Prefix.AssetServer + "/download/{pake_id}"  # 案例下载

"""  测试案例集相关  """
get_suites_url = Prefix.AssetServer + "/suites"  # 获取测试集
run_suite_url = Prefix.TaskServer + "/tasks"  # 运行测试集
get_taskassemble_url = Prefix.TaskServer + "/tasks?finished=true&page=0&pageSize=12&own=true&expandedIds={task_set_id}"  # 获取测试案例集合
queue_status_url = Prefix.TaskServer + "/tasks/queue?own=true"  # 套件运行状态检查

"""  案例判定相关  """
get_judgements_url = Prefix.AssetServer + "/cases/{caseId}/judgements"
# get_judgement_url = get_judgements_url + "/{judgementId}"
get_judgement_url = "api-asset/cases/{caseId}/judgements/{judgementId}"


# f"api-asset/cases/{caseId}/judgements/{judgementId}"
# url = f"api-asset/cases/{caseId}/judgements"

class UrlCodeType:
    unquote = "unquote"
    quote = "quote"


class File:
    """
    文件父类
    """

    def __init__(self, file_path: str):
        if not exists(file_path):
            raise FileNotFoundError
        self._file_path = file_path
        self._data = None


class FileReader(File):
    """
    读取文件
    """

    def __init__(self, file_path: str):
        super(FileReader, self).__init__(file_path)

    def read_byte(self) -> bytes:
        with open(self._file_path, 'rb') as f:
            return f.read()

    def read_str(self) -> str:
        with open(self._file_path, 'r', encoding='utf-8') as f:
            return f.read()

    def read_json(self) -> json:
        with open(self._file_path, 'r', encoding='utf-8') as f:
            return json.load(f)


class RquestApi():
    def __init__(self):
        super(RquestApi, self).__init__()
        self._headers = {"Content-Type": "application/json"}
        self._token = os.environ.get(EnvPath.token)
        self._host_ip = SimOneUrl
        self.get = "GET"
        self.post = "POST"
        self.delete = "DELETE"
        self.put = "PUT"

    def send(self, method: str, url: str, **kwargs) -> Response:
        """
        发送请求
        method: 请求方法
        url: 请求地址
        kwargs: 请求参数
        """
        self.headers.update({"Authorization": self.token})
        complete_url = urljoin(self._host_ip, url)
        data = dict()
        data['method'] = method
        data['url'] = complete_url
        data['headers'] = self.headers
        data.update(kwargs)
        print(data)
        response = request(verify=False, **data)
        try:
            print("response:%s" % str(response.content.decode("utf-8")))
            self._status_code = response.status_code
            self._response_code = response.json().get("code")
        except:
            pass
        return response

    @property
    def token(self):
        return self._token

    @property
    def headers(self):
        return self._headers

    @headers.setter
    def headers(self, value):
        self._headers = value


class LoginBusiness(RquestApi):

    def cloud_login_api(self, userinfo: dict):
        """
        云端登录API
        @param userinfo:
        @return:
        """
        return self.send(self.post, cloud_login_url, json=userinfo).json()

    def check_username_api(self, username: str):
        """
        校验用户名称是否合格
        @param username:
        @return:
        """
        payload = {'username': username}
        return self.send(self.post, login_check, json=payload).json()

    def getCheckToken(self) -> str:
        """
        校验token是否合格
        @return:
        """
        getCheckUrl = os.path.join(SimOneUrl, user_check_url)
        payload = {'username': loginData['username']}
        response = self.send(self.post, getCheckUrl, json=payload)
        checkToken = json.loads(response.content.decode("utf-8"))['data']['checkToken']
        return checkToken

    def pad(self, text):
        """
        填充函数，使被加密数据的字节码长度是block_size的整数倍
        @param text:
        @return:
        """
        length = AES.block_size
        count = len(text.encode('utf-8'))
        add = length - (count % length)
        entext = text + (chr(add) * add)
        return entext

    def str_aes(self, string: str, key: str):
        """
        aes 加密
        @param string:
        @param key:
        @return:
        """
        aes = AES.new(key.encode("utf-8"), AES.MODE_ECB)
        res = aes.encrypt(self.pad(string).encode("utf8"))
        msg = str(base64.b64encode(res), encoding="utf8")
        return msg

    def get_str_aes(self, string: str, username: str, key: str = "eGeVQh0lRyq41I41") -> str:
        '''
        @param string:
        @param username:
        @param key: AES加密的key
        @return:
        '''
        check_token = self.check_username_api(username)
        target_string = check_token["data"]["checkToken"] + string
        msg = self.str_aes(target_string, key)
        return msg

    @property
    def _cloud_std_login(self):
        """
        云端版本登陆方式
        @return:
        """
        try:
            new_login_data = copy.deepcopy(loginData)
            new_login_data['password'] = self.get_str_aes(string=new_login_data['password'],
                                                          username=new_login_data['username'])
            print('cloud login data:' + str(new_login_data))
            response = self.cloud_login_api(userinfo=new_login_data)
            print("-------", response)
            print('cloud login request result:' + str(response))
            token = response['data']['token']
            os.environ[EnvPath.token] = token
            print(token)
            return token
        except Exception as e:
            print(str(e))
            raise print('get token error ')

    @property
    def _enterprise_std_login(self):
        """
        单机版本登录方式
        @return:
        """
        try:
            getLoginUrl = os.path.join(SimOneUrl, standalone_login_url)
            response = self.send(self.get, url=getLoginUrl)
            token = json.loads(response.content.decode("utf-8"))['data']['token']
            os.environ[EnvPath.token] = token
        except Exception as e:
            print(str(e))
            token = ""
            # raise AssertionError('get token error ')
        return token


# 登录入口
class LoginPolicy():
    standalone = "standalone"
    cloud = "cloud"

    def __new__(cls, env_name):
        if env_name == cls.standalone:
            return LoginBusiness()._enterprise_std_login
        elif env_name == cls.cloud:
            return LoginBusiness()._cloud_std_login
        else:
            return print("----------input error---------------")


class Suite(RquestApi):

    def __init__(self):
        super(Suite, self).__init__()
        self._cyclical = 0
        self.category_name = "Automation_" + str(random.randint(0, 9999))

    def create_category_api(self, cate_name: str):
        '''
        创建案例库
        @param cate_name: 案例库名
        @return:
        '''
        payload = {"parentId": "", "name": cate_name}
        return self.send(self.post, categories_url, json=payload).json()

    def create_category(self, cate_name: str = None) -> str:
        '''
        创建案例库
        @param cate_name:
        @return:
        '''
        if not cate_name:
            cate_name = self.category_name
        print(f"案例库目录名称：{cate_name}")
        response = self.create_category_api(cate_name)
        cate_id = response["data"]["categoryId"]
        print(f"案例库目录 id ：{cate_id}")
        return cate_id

    def get_category_api(self):
        """
        获取案例库列表
        @return: response
        """
        return self.send(self.get, categories_url).json()

    def get_category(self, userid: str = None) -> dict:
        """
        获取案例库
        @param userid: 用户id desc：admin->builtIn
        @return:
        """
        cate_dict = {"data": {}, "parentId": {}}
        response = self.get_category_api()
        cate_dict["total"] = response["data"]["total"]
        if not userid:
            print("获取当前所有的案例库目录信息")
            for one in response["data"]["categories"]:
                cate_dict["data"].setdefault(one["name"], one["id"])
                cate_dict["parentId"].setdefault(one["name"], one["parentId"])
        else:
            print("获取用户{}的案例库目录信息".format(userid))
            for one in response["data"]["categories"]:
                if one["userId"] == userid:
                    cate_dict["data"].setdefault(one["name"], one["id"])
                    cate_dict["parentId"].setdefault(one["name"], one["parentId"])
        print("获取到的案例库->%s" % str(cate_dict))
        return cate_dict

    def get_category_case_api(self, cate_id: str):
        """
        获取当前案例库所有案例
        @param cate_name: 案例库名
        @return:
        """
        return self.send(self.get, get_cases_url.format(category=cate_id)).json()

    def get_cases_category(self, cate_id: list):
        """
        获取当前案例库的所有案例
        @param cate_id: 案例库目录id
        @return:
        """

        def url_code(url: str, way: str):
            from urllib import parse
            if way == "unquote":
                return parse.unquote(url)
            elif way == "quote":
                return parse.quote(url)

        page_size = 100
        # print("get all case id from api by category_id")
        _filter = {"keyword": "", "categories": cate_id}
        string = json.dumps(_filter).replace(" ", "")
        filter = url_code(string, UrlCodeType.quote).replace("%", "%25")
        response = self.send(self.get, get_cases_url.format(page="1", category=filter)).json()
        # get case id
        # print("get_cases_category 入参cate_id:%s" % cate_id)
        cases_num = response['data']['total']
        if cases_num >= page_size:
            if cases_num % page_size == 0:
                page = cases_num // page_size
            else:
                page = cases_num // page_size + 1
        else:
            page = 1

        def update_case_id(response, page_size):
            case_name = response['data']['caseDefs'][page_size]['name']
            case_id = response['data']['caseDefs'][page_size]['id']
            case_id_list.append(case_id)
            cases_dict.setdefault(case_name, [case_id])

        cases_dict = {}
        case_id_list = []
        # 如果案例数量是100以内
        if cases_num <= page_size:
            for i in range(cases_num):
                update_case_id(response=response, page_size=i)
        else:
            # 如果案例数量超过100了，固定获取案例数量为100个就翻页
            for i in range(page):
                response = self.send(self.get, self.get_cases_url.format(page=str(i + 1), category=filter)).json()
                # cases_num % page_size 是取整表示没有到达最后一页
                # if i == 0 or i > 0 and cases_num % page_size == 0:
                if i + 1 != page:
                    # print("xxx page_size:",page_size)
                    for j in range(page_size):
                        # print("xxx j:",j)
                        update_case_id(response=response, page_size=j)
                # 到最后一页了，因为案例数量不固定所以需要单独计算获取的个数
                else:
                    for j in range(cases_num % page_size):
                        update_case_id(response=response, page_size=j)
        return cases_dict, case_id_list

    def get_case_detail_api(self, case_id: str):
        """
        获取案例信息
        @param : /{case_id}/data
        @return: response
        """
        url = case_details_url.format(case_id=case_id)
        return self.send(self.get, url).json()

    def get_case_detail(self, case_id: str):
        """

        @param case_id: 测试案例id
        @return:
        """
        response = self.get_case_detail_api(case_id)
        return response

    # def run_task(self, caseid: list, vehicle_id: str = None):
    #     """
    #     :param caseid:
    #     :return:
    #     """
    #
    #     def creat_task_name():
    #         return "taskName_" + time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime())
    #
    #     taskname = creat_task_name()
    #     payload = {"caseIds": caseid, "taskName": taskname, "speed": 1}
    #     if vehicle_id:
    #         payload.update({"overrideVehicleId": vehicle_id})
    #     response = self.send(self.post, url=create_task_url, json=payload).json()
    #     print(f"run_task response：{response}")  # taskIds为空时代表运行案例异常
    #     data = response['data']
    #     return data['sessionId'], data['taskIds']

    def run_task(self, caseid: list, vehicle_id: str = None, withEvaluation: bool = False, version: float = 3.5):
        """
        运行测试任务集合
        Run task set
        @param caseid: caseid
        @param vehicle_id: vehicle_id
        @param withEvaluation: withEvaluation
        @param version: version
        @return:
        """
        task_name = "taskName_" + time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime())
        if version >= 3.5:
            payload = {"caseIds": caseid,
                       "taskName": task_name,
                       "withEvaluation": withEvaluation,
                       "controllers": [{"id": "Default", "name": "默认控制器", "algorithmId": "SimOneDriver"},
                                       {"id": "AutoDrive", "name": "自驾控制器", "algorithmId": "SimOneDriver"}]}
        else:
            payload = {"caseIds": caseid, "taskName": task_name, "speed": 1}
        if vehicle_id:
            payload.update({"overrideVehicleId": vehicle_id})
        response = self.send(self.post, url=create_task_url, json=payload).json()

        data = response['data']
        return data['sessionId'], data['taskIds']

    def stop_task_api(self, payload: dict):
        """
        task停止API
        @param payload: eg  {"ids":["f9e096f6-78ff-431a-a5e2-24a2de4117df"]}
        @return:
        """
        return self.send(self.post, stop_task_url, json=payload).json()

    def stop_sessions_api(self, payload: dict):
        """
        sessions停止API
        @param payload: eg  {"ids":["f9e096f6-78ff-431a-a5e2-24a2de4117df"]}
        @return:
        """
        return self.send(self.post, stop_sessions_url, json=payload).json()

    def stop_task(self, task_id: list, sessions_id: list):
        """
        停止任务和会话
        @param task_id:
        @param sessions_id:
        @return:
        """
        task_payload = {"ids": task_id}
        self.stop_task_api(task_payload)
        sessions_id = {"ids": sessions_id}
        self.stop_sessions_api(sessions_id)

    def pause_task_api(self, task_id: str):
        """
        暂停任务
        @param task_id:
        @return:
        """
        return self.send(self.post, pause_task_url.format(task_id=task_id), json={}).json()

    def resume_task_api(self, task_id: str):
        """
        暂停任务后开始
        @param task_id:
        @return:
        """
        return self.send(self.post, resume_task_url.format(task_id=task_id), json={}).json()

    def delete_sessions_api(self, payload: dict):
        """
        sessions删除API
        @param payload: eg  {"ids":["f9e096f6-78ff-431a-a5e2-24a2de4117df"]}
        @return:
        """
        return self.send(self.post, delete_sessions_url, json=payload).json()

    def delete_task_api(self, payload: dict):
        """
        task删除API
        @param payload: eg  {"ids":["f9e096f6-78ff-431a-a5e2-24a2de4117df"]}
        @return:
        """
        return self.send(self.post, delete_task_url, json=payload).json()

    def delete_task(self, sessions_id: list, task_id: list):
        """
        删除任务和会话
        @param sessions_id:
        @param task_id:
        @return:
        """
        sessions_id = {"ids": sessions_id}
        self.delete_sessions_api(sessions_id)
        task_payload = {"ids": task_id}
        self.delete_task_api(task_payload)

    def import_vehicle_api(self, payload: dict):
        """
        导入主车
        @param payload: eg {"vehicleData": {"byId": {vehicle_id: vehicle_data},
                                      "allIds": [vehicle_id]}}
        @return:
        """
        return self.send(self.post, import_vehicle_url, json=payload).json()

    def get_vehicle_data(self, file_path: str):
        vehicle_info = FileReader(file_path).read_json()
        vehicle_id = vehicle_info.get("id")
        return vehicle_info, vehicle_id

    def import_vehicle(self, file_path: str) -> str:
        """
        导入主车
        @param file_path: 主车文件
        @return: 主车id
        """
        vehicle_data, vehicle_id = self.get_vehicle_data(file_path)
        payload = {"vehicleData": {"byId": {vehicle_id: vehicle_data},
                                   "allIds": [vehicle_id]}}
        result = self.import_vehicle_api(payload)
        return result["data"]["id"]

    def get_vehicle_api(self):
        """
        获取主车信息
        @return:
        """
        return self.send(self.get, get_vehicle_url).json()

    def get_vehicle(self, userid: str = None):
        """
        根据用户信息获取主车信息
        @param userid:
        @return:
        """
        global vehicle_data
        vehicle_data = {}
        res = self.get_vehicle_api()
        # print(f"get_vehicle_api response ->: {res}")
        data = res["data"]["list"]["byId"]
        id_list = res["data"]["list"]["allIds"]
        if userid:
            for id in id_list:
                if data[id]["userId"] == userid:
                    vehicle_data.setdefault(data[id]["name"], data[id]["id"])
        else:
            for id in id_list:
                vehicle_data.setdefault(data[id]["userId"], {}).update({data[id]["name"]: data[id]["id"]})
        print("获取到的主车信息->：{}".format(str(vehicle_data)))
        return vehicle_data

    def get_vehicle_id(self, vehicle_name: list) -> list and dict:
        """
        根据主车名称获取主车ID
        @param vehicle_name:
        @return:
        """
        vehicle_id_dict = {}
        vehicle_id_list = []
        vehicle_list = []
        for i in vehicle_name:
            for k, v in self.get_vehicle().items():
                vehicle_list.append(v)
            for vehicle_dict in vehicle_list:
                # print("vehicle_dict", vehicle_dict)
                vehicle_dict_key = dict(vehicle_dict).items()
                for vehicle_dict_k, vehicle_dict_v in vehicle_dict_key:
                    if i in vehicle_dict_k:
                        vehicle_name_id = vehicle_dict[i]
                        vehicle_id_list.append(vehicle_name_id)
                        vehicle_id_dict.setdefault(i, vehicle_name_id)

        print("vehicle_id_list->:", vehicle_id_list, "\nvehicle_id_dict->:", vehicle_id_dict)
        return vehicle_id_list, vehicle_id_dict

    def delete_vehicles_api(self, vehicles_id: str):
        """
        删除主车
        @param vehicles_id: 主车id
        @return:
        """
        url = delete_vehicle_url.format(vehicles_id=vehicles_id)
        return self.send(self.delete, url)

    def delete_vehicle(self, id: str):
        """
        删除主车
        @param id: 主车id
        @return:
        """
        self.delete_vehicles_api(id)

    def get_suite_api(self):
        """
        get_suite
        @return:
        """
        return self.send(self.get, url=get_suites_url).json()

    def get_suite(self, suite_name: str = None):
        """
        :return:
        """
        response = self.get_suite_api()
        data = response['data']
        suite_dict = {}
        for id in data['allIds']:
            suite_dict.setdefault(data['byId'][id]['name'], {}).update({"caseIds": data['byId'][id]['caseIds']})
        print("suite_dict", suite_dict)
        if not suite_name:
            return suite_dict
        else:
            # print("suite_dict[suite_name]:",suite_dict[suite_name])
            return suite_dict[suite_name]

    def run_suite_api(self, payload: dict):
        """
        run_suite
        @param payload: payload
        @return:
        """
        return self.send(self.post, url=run_suite_url, json=payload).json()

    def run_suite(self, suite_name: str, taskName: str = None, vehicle_id: str = None):
        if taskName is None:
            def creat_task_name():
                return "taskName_" + time.strftime("%Y-%m-%d_%H:%M:%S", time.localtime())

            taskName = creat_task_name()
        caseid_list = self.get_suite(suite_name)['caseIds']
        payload = {'caseIds': caseid_list,
                   'taskName': taskName}
        if vehicle_id:
            # vehicle_module = VehicleBusiness()
            # vehicle_module.get_vehicle()
            payload.update({"overrideVehicleId": vehicle_id})
        response = self.run_suite_api(payload)
        data = response['data']
        return data['sessionId'], data['taskIds']

    def suite_queue_api(self):
        """
        suite_queue
        @return:
        """
        return self.send(self.get, url=queue_status_url).json()

    def suite_queue_check(self, n=10):
        """
        @param n:cycle index
        @return:
        """
        if n == 1:
            print("-----------------------The test case run fail--------------------------------------")
            return False
        while (1):
            try:
                assert self.suite_queue_api()
                response = self.suite_queue_api()
                assert response["code"] == 0
            except Exception as e:
                return -1
            queue_info = response["data"]
            running, pending, waiting = queue_info["running"], queue_info["pending"], queue_info["waiting"]

            if running == 0 and pending == 0 and waiting == 0:
                print("-----------------------The test case run finish--------------------------------------")
                return True
            else:
                time.sleep(interval)

    def get_result(self, task_id: list, index: int = None):
        """
        :param task_id:
        :return:
        """
        task_id_str = ",".join(task_id)
        # print(task_id_str)
        response = self.send(self.get, url=result_url.format(task_id=task_id_str)).json()
        data = response["data"]["tasks"]
        result = []
        for one in data:
            result.append({"pass": one["pass"], "is_ended": True if one["key"] == "ended" else False})
        if not index:
            return result
        else:
            return result[index]

    def is_ended(self, task_id: list, case_name=None):
        """
        判断案例是否运行结束
        @param task_id: 任务id
        @param case_name: 案例名称
        @return:
        """
        interval = 10
        while (1):
            result = self.get_result(task_id, -1)
            if result["is_ended"]:
                print('Case status：end of run')
                if case_name:
                    print(f'Name of the current ending case->{case_name}')
                return False
            else:
                print('Case status：in progress')
                if case_name:
                    print(f'Name of the current running case->{case_name}')
                time.sleep(interval)

    def get_taskassemble_api(self, task_set_id):
        '''
        获取测试案例集
        @param
        @return:
        '''
        return self.send(self.get, get_taskassemble_url.format(task_set_id=task_set_id)).json()

    def get_task_id_of_task_set(self, task_set_id: str) -> list:
        """
        获取任务集合中所有测试案例的task_id
        @param task_set_id: 任务集合id
        @return: list
        """
        response = self.get_taskassemble_api(task_set_id)
        _task_id_list = response["data"]["list"]
        # print("---------------------------------task_id_list-----------------------")
        # print(_task_id_list)
        index = 0
        task_id_list = []
        for i in _task_id_list:
            index += 1
            # print(f"------------------------第{index}个元素----------------")
            # print(i)
            if i['parentId'] == task_set_id:
                # print(i)
                task_id_list.append(i["id"])
        # print("task_id_list",task_id_list)
        return task_id_list

    def get_task_result_api(self, task_id: str):
        """
        获取指定task的结果
        @param task_id:
        @return:
        """
        return self.send(self.get, task_result_url.format(id=task_id)).json()

    def get_task_result(self, task_id_list: list = None) -> list:
        """
        获取任务集中的  案例名称，caseId，task_id,运行结果
        @param task_id_list: 任务id列表
        @param task_set_id: 任务集合id
        @return:
        """

        task_result_list = []
        for task_id in task_id_list:
            result = self.get_task_result_api(task_id)
            case_name = result["data"]["tasks"][0]["case"]["name"]
            case_id = result["data"]["tasks"][0]["caseId"]
            task_id = result["data"]["tasks"][0]["id"]
            task_result = result["data"]["tasks"][0]["pass"]
            if task_result != True: task_result = False
            task_result_list.append({"case_name": case_name,
                                     "case_id": case_id,
                                     "task_id": task_id,
                                     "task_result": task_result})
        print("task_result_list->", task_result_list)
        return task_result_list

    def import_map_api(self, payload: dict, files: dict):
        """
        导入地图API
        @param payload:传参字典
        @param files: 传参文件
        @return:
        """
        self.headers = {}
        return self.send(self.post, import_map_url, data=payload, files=files).json()

    def import_map(self, xodr_path: str, thumbnail_path: str):
        """
        导入地图方法
        @param xodr_path: 地图文件
        @param thumbnail_path: 地图对应的图像
        @return:
        """
        # map_name = "map_" + str(random.randint(0, 9999))
        payload = {"params": json.dumps(
            {"category": "customized", "id": "", "name": os.path.splitext(os.path.basename(xodr_path))[0], "size": 512,
             "ppm": 10, "bgColor": "#dddddd", "reproject": True, "reprojectOrigin": False, "reprojectOriginLat": 0,
             "reprojectOriginLng": 0, "tags": [], "notes": "",
             "header": {"minX": -210.20535534122396, "minY": -149.68815701999185, "minZ": -1.862645149230957e-9,
                        "maxX": 237.95535534122394, "maxY": 135.43815701999196, "maxZ": 2.7940070024635385e-9,
                        "centerX": 97.12480158531203, "centerY": 24.463606820251727, "centerZ": 100,
                        "localEnuExt": "6378137,0,0;0,1,0;0,0,1;1,0,0"}})}
        files = {'xodr': open(xodr_path, 'rb'), "thumbnail": open(thumbnail_path, 'rb')}
        result = self.import_map_api(payload, files)
        if result["code"] == 0:
            print(f"import map {xodr_path}success")
        else:
            raise f"import map {xodr_path} fail"

    def get_map_api(self):
        """
        获取地图
        @return:
        """
        return self.send(self.get, get_map_url).json()

    def get_map_id(self, userid: str = None, map_name: str = None):
        """
        按条件获取地图信息，默认获取所有地图
        @param userid: 用户id
        @param map_name: 地图名字
        @return:
        """
        global map_data
        map_data = {}
        try:
            result = self.get_map_api()
            # print(len(result['data']['maps']))
            map_info = result['data']['maps']

            if userid:
                for map in map_info:
                    if map["userId"] == userid:
                        map_data.setdefault(map["name"], map["id"])
            elif map_name:
                for map in map_info:
                    if map["name"] == map_name:
                        map_data = {map["name"]: map["id"]}
            else:
                for map in map_info:
                    map_data.setdefault(map["userId"], {}).update({map["name"]: map["id"]})
            return map_data

        except Exception as e:
            print(e)

    def delete_map_api(self, payload: dict):
        """
        删除地图
        @param payload: eg：{ids: ["27a0bbc4-5d4d-48c1-9187-62df794dadae"]}
        @return:
        """
        return self.send(self.post, delete_map_url, json=payload).json()

    def delete_map(self, id: list):
        """
        批量删除地图
        @param id: 地图id列表
        @return:
        """
        print("删除的地图列表-》{}".format(str(id)))
        payload = {"ids": id}
        self.delete_map_api(payload)

    def get_judgements_api(self, caseId, judgementId=None):
        """
        获取判定信息API
        @param caseId: 案例ID
        @param judgementId: 判定ID
        @return:
        """
        if judgementId:
            url = get_judgement_url.format(caseId=caseId, judgementId=judgementId)
        else:
            url = get_judgements_url.format(caseId=caseId)
        response = self.send(self.get, url).json()
        return response

    def get_judgements_method(self, caseId: str, judgementId: str = None):
        """
        获取判定信息
        @param caseId: 案例ID
        @param judgementId: 判定ID
        @return:
        """
        response = self.get_judgements_api(caseId, judgementId)
        print("得到的扩展判定信息：", response["data"][1])
        return response

    def update_judgement_api(self, caseId, judgementId="collision", payload: dict = None):
        """
        @param caseId: caseId
        @param judgementId: judgementId
        @return:
        """
        if not payload:
            payload = {"schema": "judgement", "settings": {"logLevel": "error", "action": "failure", "logInfo": ""},
                       "scope": {"size": {"x": 10, "y": 10, "z": 0}, "heading": {"w": 1, "x": 0, "y": 0, "z": 0},
                                 "position": {"x": 0, "y": 0, "z": 0},
                                 "type": "global"}, "builtIn": True,
                       "name": "碰撞", "lock": True, "id": "collision",
                       "type": "collision", "category": "general",
                       "conditions": [], "userId": "admin",
                       "enabled": True}
        response = self.send(self.put, get_judgement_url.format(caseId=caseId, judgementId=judgementId),
                             data=json.dumps(payload))
        return response

    def update_judgement_method(self, caseId, judgementId="collision"):
        __collision = {"schema": "judgement", "settings": {"logLevel": "error", "action": "failure", "logInfo": ""},
                       "scope": {"size": {"x": 10, "y": 10, "z": 0}, "heading": {"w": 1, "x": 0, "y": 0, "z": 0},
                                 "position": {"x": 0, "y": 0, "z": 0},
                                 "type": "global"}, "builtIn": True,
                       "name": "碰撞", "lock": True, "id": "collision",
                       "type": "collision", "category": "general",
                       "conditions": [], "userId": "admin",
                       "enabled": True}
        payload = json.dumps(__collision)
        judgement_url = "api-asset/cases/{caseId}/judgements/{judgementId}"
        response = self.send(self.put, judgement_url.format(caseId=caseId, judgementId=judgementId), data=payload)
        print("更新扩展判定信息")
        print("status_code:", response.status_code)


def main(category_name: str, case_name: str = None, vehicle_name=None, version: float = 3.5):
    """
    运行任务的入口主函数
    @param category_name: category_name
    @param case_name:
    @param vehicle_name:vehicle_name
    @param version: version
    @return:
    """
    suite = Suite()
    suite.get_category()
    cate_id = suite.get_category()
    cate_name = [cate_id["data"][category_name]]
    cases_dict, case_id_list = suite.get_cases_category(cate_name)

    # 主车控制相关逻辑
    if vehicle_name:
        vehicle_dict = suite.get_vehicle_id([vehicle_name])[1]
        if vehicle_name not in vehicle_dict.keys():
            print(f"vehicle_name：{vehicle_name} inexistence")
            return
        vehicle_id = vehicle_dict[vehicle_name]
    else:
        vehicle_id = None
    print(f"vehicle_name:{vehicle_name},vehicle_id:{vehicle_id}")

    # 案例名称逻辑
    if case_name:
        case_id_list = cases_dict[case_name]
        print(f" case_name:{case_name}")

    # 启动案例
    session_id, task_ids = suite.run_task(case_id_list, vehicle_id=vehicle_id, version=version)
    time.sleep(10)
    # suite.stop_task(task_id=task_ids, sessions_id=[session_id])
    # 等待案例运行完毕
    falg = suite.suite_queue_check()
    if falg is True:
        # 获取案例运行结果
        suite.get_task_result(task_ids)


SimOneUrl = "http://127.0.0.1:30083/"
loginData = {
    "username": 'admin',
    "password": 'admin',
}
# LoginPolicy("cloud")
LoginPolicy("standalone")
if __name__ == '__main__':
    # main("转向冲突", "转向冲突8")
    fire.Fire(main)
    # eg:
    #    1. Run one case :python runSimOneCase.py --category_name='入门案例' --case_name='构建标准案例2.0'
    #    2. Run one case and switch the vehicle :python runSimOneCase.py --category_name='入门案例' --case_name='构建标准案例2.0' --vehicle_name='手动控制-默认'
    #    3. Run all cases under the case category :python runSimOneCase.py --category_name='入门案例'
    #    4. Run all cases under the case category and switch the vehicle :python runSimOneCase.py --category_name='入门案例’ --vehicle_name='手动控制-默认'
