# -*- coding:utf-8 -*-
import copy
import importlib
import json
import os
import random
import re
import sys
import string
import time
import traceback


def get_project_root_path(path="base_framework"):
    """
    获取项目目录
    """
    o_path = os.getcwd()
    try:
        project_path = re.search(r"(.*%s)" % path, o_path).group(1)
        return os.path.abspath(os.path.join(project_path, os.path.pardir))
    except:
        pass


Project_Path = get_project_root_path()
sys.path.append(Project_Path)

from base_framework.platform_tools.Keywords_service.keyword_service1 import SetAttr, log


def load_module_from_file(file_path, team):
    module_file = re.search(r"(%s\\.*)\.py" % team, file_path)
    if not module_file:
        module_file = re.search(r"(%s.*)\.py" % team.lower(), file_path)
    temp = module_file.group(1)
    temp = temp.replace(os.sep, ".")
    # try:
    #     module = importlib.import_module(temp)
    # except Exception as err:
    #     temp = re.sub(r"%s\." % team, "%s." % team.lower(), temp)
    #     module = importlib.import_module(temp)
    return importlib.import_module(temp)


class ITCaseFileOperation(object):
    def __init__(self, team, kw_instance):
        self.kw = kw_instance
        self.all_url = kw_instance.all_url
        self.kw_class_name = kw_instance.kw_class
        self.case_dir = os.path.abspath(os.path.join(Project_Path, team, "test_case", "TestCase", "1.接口"))
        self.env_path = os.path.abspath(
            os.path.join(Project_Path, team, "test_case", "Resource", "AdapterKws", "env.robot"))

    def _check_case_file_exist(self, file_path):
        if os.path.exists(file_path) and os.path.isfile(file_path):
            return True
        else:
            return False

    def check_case_exist(self, case_path, case_name):
        if self._check_case_file_exist(case_path):
            with open(case_path, "r", encoding="utf-8") as f:
                for line in f.readlines():
                    if line.startswith(case_name):
                        return True
                else:
                    return False
        else:
            return False

    def generate_case_file(self, file_path):
        if not self._check_case_file_exist(file_path):
            dirname = file_path[:-len(os.path.basename(file_path))]
            if not os.path.exists(dirname):
                os.makedirs(dirname)
            self.write_content_to_case_file(file_path, self.generate_env_releate_path(dirname))
        else:
            with open(file_path, "r", encoding="utf-8") as f:
                if f.readlines():
                    if "\n" != f.readlines()[-1]:
                        self.write_content_to_case_file(file_path, "\n")

    def generate_env_releate_path(self, file_path):
        return "*** Settings ***\nResource          " + os.path.relpath(self.env_path,
                                                                        file_path).replace("\\",
                                                                                           "/") + "\n\n*** Test Cases ***\n"

    def _check_case_file_resource(self, file_path):
        """
        确定case文件中是否有关键字
        """
        with open(file_path, "a+", encoding="utf-8") as f:
            content_list = f.readlines()
            if "*** Keywords ***\n" not in content_list:
                return True
            else:
                kw_index = content_list.rindex("*** Keywords ***\n")
                for index in range(kw_index, len(content_list) + 1):
                    if "*** Test Cases ***\n" == content_list[index]:
                        status = True
                    if "*** Keywords ***\n" == content_list[index]:
                        status = False
                return status

    def write_content_to_case_file(self, file_path, content):
        status = self._check_case_file_resource(file_path)
        with open(file_path, "a+", encoding="utf-8") as f:
            if status:
                f.write(content)
            else:
                content = "*** Test Cases ***\n" + content
                f.write(content)


class ITCaseContentOperation(object):
    def __init__(self, team, kw_instance):
        self.team = team
        self.file = ITCaseFileOperation(team, kw_instance)
        self.doc_content_row_temp = "    ...    | {} | {} | {} |"
        self.normal_1001 = None
        self.un_expect_list = None
        self.case_string = None

    def _generate_case_name(self, interface_name, case_type, case_des):
        return "-".join([interface_name, case_type, case_des])

    def _check_interface_confirm(self, interface_info):
        if not interface_info.confirmed:
            raise Exception("接口%s未确认，请先确认接口参数。" % interface_info.name)

    def generate_case_body_all_1001_array(self, request_demo, parameters):
        temp_list = list()
        demo_copy = copy.deepcopy(request_demo)
        for key, value in request_demo.items():
            if not value:
                demo_copy.pop(key)
        if len(demo_copy.keys()) == 1:
            demo_copy = demo_copy.pop(list(demo_copy.keys())[0])
        dict_para, self.un_expect_list, _, _ = self._analysis_case_parameters_to_dict(parameters)
        demo_add_values = self._analysis_case_parameters_to_value(demo_copy, dict_para)
        data_list = self._analysis_dict_to_body_value(demo_copy, demo_add_values)
        if isinstance(demo_copy, list):
            for item in data_list:
                temp_list.append([item])
            data_list = temp_list
        return data_list

    def _generate_parameter_to_dict(self, parameters):
        dict_temp = dict()
        for parameter in parameters:
            parameter_attr = SetAttr(parameter)
            dict_temp[parameter_attr.name] = parameter_attr
        return dict_temp

    def _analysis_case_parameters_to_value_empty_dict(self, request_demo, parameters, type=None):
        """
        循环生成缺少某个参数的值，其它正确的参数组合列表
        """
        parameter_expect_list = list()
        expect_lenth = 0
        un_expect_lenth = 0
        parameter_expect_dict = dict()
        parameter_un_expect_dict = dict()
        for key, parameter_attr in parameters.items():
            if parameter_attr.normal_values:
                parameter_expect_dict[parameter_attr.name] = parameter_attr.normal_values.split(",")
            else:
                parameter_expect_dict[parameter_attr.name] = [
                    self._generate_body_expect_type_value(parameter_attr.type)]

            if len(parameter_expect_dict[parameter_attr.name]) > expect_lenth:
                expect_lenth = len(parameter_expect_dict[parameter_attr.name])

            if parameter_attr.exception_values:
                parameter_un_expect_dict[parameter_attr.name] = parameter_attr.exception_values.split(",")
            else:
                parameter_un_expect_dict[parameter_attr.name] = [
                    self._generate_body_un_expect_type_value(parameter_attr.type)]

            if len(parameter_un_expect_dict[parameter_attr.name]) > un_expect_lenth:
                un_expect_lenth = len(parameter_un_expect_dict[parameter_attr.name])

        for key in parameter_expect_dict.keys():
            if key not in json.dumps(request_demo):
                continue
            value = copy.copy(parameter_expect_dict)
            value[key] = ['NULL']
            if parameters.get(key).is_need == 1:
                status = "FAIL"
            else:
                status = "PASS"
            if type == "1102":
                name = "缺少参数%s" % key
            else:
                name = "缺少参数%s的值" % key
            parameter_expect_list.append([value, status, name])
        return parameter_expect_list

    def _distinguish_parameters_by_is_needed(self, parameters):
        """
        将必填参数和非必须参数分开成2个列表
        """
        need_parameters = list()
        no_need_parameters = list()
        for parameter in parameters:
            parameter_attr = SetAttr(parameter)
            if parameter_attr.is_need != 0:
                need_parameters.append(parameter_attr)
            else:
                no_need_parameters.append(parameter_attr)
        return need_parameters, no_need_parameters

    def _replace_null_value_no_need_parameters(self, demo, no_need_parameter_attrs):
        """
        将所有非必填参数置空
        """
        really_body = copy.deepcopy(demo)
        for parameter_attr in no_need_parameter_attrs:
            if re.search(r"\"%s\"" % parameter_attr.name, demo):
                check_para = r"\"%s\":\s[\[\{]" % parameter_attr.name
                if re.search(check_para, demo):
                    continue
                try:
                    expect_value = parameter_attr.normal_values.split(",")[0]
                except Exception as err:
                    log.error(err)
                    raise Exception("接口参数%s无正常值，请先确认接口参数。" % parameter_attr.name)
                patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
                replace1 = "\"%s\": \"NULL\"" % parameter_attr.name
                really_body = re.sub(patten1, replace1, really_body)
        return really_body

    def generate_case_body_all_1101_array(self, request_demo, parameters):
        """
        生成1101用例对应的所有请求参数组合
        """
        body_array = list()
        need, no_need = self._distinguish_parameters_by_is_needed(parameters)
        demo_json = json.dumps(request_demo, ensure_ascii=False)
        if no_need:
            no_need_demo_json = self._replace_null_value_no_need_parameters(demo_json, no_need)
            body_array.append([json.loads(no_need_demo_json), "PASS", "所有非必填参数为空"])
        for item in need:
            parameter_attr = copy.copy(item)
            demo_json_copy = copy.copy(demo_json)
            if re.search("\"%s\"" % parameter_attr.name, demo_json_copy):
                check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
                if re.search(check_para, demo_json_copy):
                    continue
                name = "缺少参数%s" % parameter_attr.name
                try:
                    expect_value = parameter_attr.normal_values.split(",")[0]
                except Exception as err:
                    log.error(err)
                    raise Exception("接口参数%s无正常值，请先确认接口参数。" % parameter_attr.name)
                if parameter_attr.type == "array":
                    patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
                    replace1 = "\"%s\": []" % parameter_attr.name
                else:
                    patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
                    patten1 = patten1.replace("{", r"\{")
                    patten1 = patten1.replace("}", r"\}")
                    patten1 = patten1.replace("[", r"\[")
                    patten1 = patten1.replace("]", r"\]")
                    patten1 = patten1.replace("$", r"\$")
                    replace1 = "\"%s\": \"NULL\"" % parameter_attr.name
                really_body = re.sub(patten1, replace1, demo_json_copy)
                if parameter_attr.is_need == 1:
                    status = "FAIL"
                else:
                    status = "PASS"
                body_array.append([json.loads(really_body), status, name])
        return body_array

    def _clean_all_none_json_char(self, really_body):
        """
        清除1102场景删除缺少参数后不规则的字符串内容
        """
        really_body = re.sub(",\s,", ",", really_body)
        really_body = re.sub("\[\s?,", "[", really_body)
        really_body = re.sub("\{\s?,", "{", really_body)
        really_body = re.sub(",\s\]", "]", really_body)
        really_body = re.sub(",\s\}", "}", really_body)
        really_body = re.sub("\s,", "", really_body)
        return really_body

    def _replace_null_all_no_need_parameters(self, demo, no_need_parameter_attrs):
        """
        将所有非必填参数置空
        """
        really_body = copy.deepcopy(demo)
        for parameter_attr in no_need_parameter_attrs:
            if re.search(r"\"%s\"" % parameter_attr.name, demo):
                check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
                if re.search(check_para, demo):
                    continue
                try:
                    expect_value = parameter_attr.normal_values.split(",")[0]
                except Exception as err:
                    log.error(err)
                    raise Exception("接口参数%s无正常值，请先确认接口参数。" % parameter_attr.name)
                if parameter_attr.type == "array":
                    patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
                else:
                    patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
                replace1 = ""
                really_body = re.sub(patten1, replace1, really_body)
                really_body = self._clean_all_none_json_char(really_body)
        return really_body

    def generate_case_body_all_1102_array(self, request_demo, parameters):
        """
        生成1102用例对应的所有参数组合
        """
        body_array = list()
        need, no_need = self._distinguish_parameters_by_is_needed(parameters)
        demo_json = json.dumps(request_demo, ensure_ascii=False)
        if no_need:
            no_need_demo_json = self._replace_null_all_no_need_parameters(demo_json, no_need)
            body_array.append([json.loads(no_need_demo_json), "PASS", "所有非必填参数均缺失"])
        for item in need:
            parameter_attr = copy.copy(item)
            demo_json_copy = copy.copy(demo_json)
            if re.search(r"\"%s\"" % parameter_attr.name, demo_json_copy):
                check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
                if re.search(check_para, demo_json_copy):
                    continue
                name = "缺少参数%s" % parameter_attr.name
                expect_value = parameter_attr.normal_values.split(",")[0]
                if parameter_attr.type == "array":
                    patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
                else:
                    patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
                    patten1 = patten1.replace("{", r"\{")
                    patten1 = patten1.replace("}", r"\}")
                    patten1 = patten1.replace("[", r"\[")
                    patten1 = patten1.replace("]", r"\]")
                    patten1 = patten1.replace("$", r"\$")
                replace1 = ""
                really_body = re.sub(patten1, replace1, demo_json_copy)
                really_body = self._clean_all_none_json_char(really_body)
                if parameter_attr.is_need == 1:
                    status = "FAIL"
                else:
                    status = "PASS"
                body_array.append([json.loads(really_body), status, name])
        return body_array

    def generate_case_body_all_1201_array(self, request_demo, parameters):
        """
        生成1201用例对应的所有参数组合
        """
        body_array = list()
        demo_json = json.dumps(request_demo, ensure_ascii=False)
        for item in parameters:
            parameter_attr = SetAttr(item)
            if re.search(r"\"%s\"" % parameter_attr.name, demo_json):
                check_para = r"\"%s\":\s\{|\"%s\":\s\[\{" % (parameter_attr.name, parameter_attr.name)
                if re.search(check_para, demo_json):
                    continue
                for un_expect_item in self.un_expect_list.get(parameter_attr.name):
                    name = "参数%s使用异常值%s" % (parameter_attr.name, un_expect_item)
                    demo_json_copy = copy.copy(demo_json)
                    expect_value = parameter_attr.normal_values.split(",")[0]
                    if parameter_attr.type == "array":
                        patten1 = r"\"%s\":\s\[\"%s\"\]" % (parameter_attr.name, expect_value)
                        replace1 = '"%s": ["%s"]' % (parameter_attr.name, un_expect_item)
                    else:
                        patten1 = r"\"%s\":\s\"%s\"" % (parameter_attr.name, expect_value)
                        patten1 = patten1.replace("{", r"\{")
                        patten1 = patten1.replace("}", r"\}")
                        patten1 = patten1.replace("[", r"\[")
                        patten1 = patten1.replace("]", r"\]")
                        patten1 = patten1.replace("$", r"\$")
                        replace1 = '"%s": "%s"' % (parameter_attr.name, un_expect_item)
                    really_body = re.sub(patten1, replace1, demo_json_copy)
                    status = "FAIL"

                    body_array.append([json.loads(really_body), status, name])
        return body_array

    def create_case_content(self, result_path, interface_info, parameters, demo, case_type, tags=None):
        """
        生成用例的所有内容
        """
        self._check_interface_confirm(interface_info)
        body_content = list()
        doc = self.generate_case_doc(interface_info, tags=tags, demo=demo)
        case_file, _ = self.generate_case_file_path(interface_info)
        interface_name = interface_info.name
        if not parameters:
            body = self.generate_case_body_content(interface_info.in_url, doc, interface_name, case_type,
                                                   interface_info.interface_describe, None, status="PASS")

        else:
            try:
                body_array = self.generate_case_body_all_1001_array(demo, parameters)
                self.normal_1001 = body_array[0]
            except TypeError:
                log.warning(traceback.print_exc())
                body_array = []
                self.normal_1001 = {}
            if case_type == "1001":
                try:
                    body = self.generate_case_body_content(interface_info.in_url, doc, interface_name, case_type,
                                                           interface_info.interface_describe, body_array, status="PASS")
                except Exception as err:
                    msg = "生成用例%s,%s失败原因如下:%s" % (interface_info.type, interface_info.in_url, traceback.print_exc())
                    log.error(msg)
                    self.file.write_content_to_case_file(result_path, msg + "\n")

            elif case_type == "1101" or case_type == "1102" or case_type == "1201":
                body_temp_list = []
                # parameters_temp = self._generate_parameter_to_dict(parameters)
                try:
                    body_array = eval(
                        "self.generate_case_body_all_%s_array(self.normal_1001, parameters)" % case_type)
                    if case_type == "1101":
                        name = "缺少参数值"
                    elif case_type == "1102":
                        name = "缺少参数key和值"
                    elif case_type == "1201":
                        name = "参数使用异常值"
                    else:
                        name = ""
                    body_tmp = self.generate_case_body_content(interface_info.in_url, doc, interface_name,
                                                               case_type,
                                                               name, body_array, status="PASS")
                    body_temp_list.append(body_tmp)
                    body = "".join(body_temp_list)
                except Exception as err:
                    msg = "生成用例%s,%s失败原因如下:%s" % (interface_info.type, interface_info.in_url, traceback.print_exc())
                    log.error(msg)
                    self.file.write_content_to_case_file(result_path, msg + "\n")
                    raise err
        body_content.append(body)
        self.file.write_content_to_case_file(case_file, "\n".join(body_content))
        msg = "接口url：%s,%s,生成case%s成功！路径为：%s" % (interface_info.type, interface_info.in_url, case_type, case_file)
        log.info(msg)
        self.file.write_content_to_case_file(result_path, msg + "\n")
        return msg

    def generate_case_body_content(self, url, doc, interface_name, case_type, description, body_para, status="PASS"):
        body_content = list()
        case_name = self._generate_case_name(interface_name, case_type, description)
        body_content.append(case_name)
        body_content.append(doc)
        # 如何需要自动生成1001类型用例的请求body数据，请将304/305行放开，并把306~310注释
        request = self._generate_case_body_content(url, body_content=body_para, status=status)
        body_content.append(request)
        # if case_type != "1001":
        #     request = self._generate_case_body_content(url, body_content=body_para, status=status)
        #     body_content.append(request)
        # else:
        #     body_content.append("    #请自行添加用例请求数据！\n")
        return "\n".join(body_content)

    def _generate_case_body_content(self, url, body_content=None, status="PASS"):
        body_list = []
        if body_content is None:
            try:
                body_request = "    ${resp}    %s" % (self.file.all_url.get(url)[1])
            except Exception as err:
                log.error(traceback.print_exc())
                body_request = "    #url: %s 无法找到对应的关键字，请检查并更新！" % url
            body_list.append(body_request)
            body_list.append("    Log    ${resp}")
            if self.team.upper() in ["TMO"]:
                body_validate_success = "    check_rf    ${resp}    %s" % '请自行添加检查结果'
            else:
                body_validate_code = "    Should Be Equal    ${resp['code']}    ${200}"
                body_validate_success = "    Should Be True    ${resp['success']}"
                body_list.append(body_validate_code)
            body_list.append(body_validate_success)
        else:
            if not body_content:
                body_create = "    #request_demo无内容或者parameters在数据表中不全，请先检查再生成 \n    ${body}    Evaluate    %s" % body_content
                body_list.append(body_create)
            count = 0
            for real_body in body_content:
                result = {"message": "", "code": 200, "success": True}
                temp = copy.copy(real_body)
                if len(real_body) == 3 and isinstance(real_body, list):
                    if real_body[1] == "PASS" or real_body[1] == "FAIL":
                        real_body = temp[0]
                        status = temp[1]
                        case_description = temp[2]
                        body_list.append("    #%s" % case_description)
                        try:
                            module = load_module_from_file(self.file.kw.kw_file_path, self.team)
                            importlib.reload(module)
                            if isinstance(real_body, list):
                                temp_type = "*"
                            else:
                                temp_type = "**"
                            result = eval(
                                "%s.%s().%s(%sreal_body)" % (
                                    "module", self.file.kw_class_name, self.file.all_url.get(url)[1], temp_type))
                        except:
                            msg = "#url: %s 无法通过参数得到请求结果！" % url
                            log.warning(real_body)
                            log.warning(msg)
                            log.warning(traceback.print_exc())
                if "${time}" in str(real_body):
                    body_list.append("    ${time}    get time    epoch")
                body_create = "    ${body_%s}    Evaluate    %s" % (count, real_body)
                try:
                    if isinstance(real_body, list):
                        body_request = "    ${resp_%s}    %s    %s" % (
                            count, self.file.all_url.get(url)[1], "@{body_%s}" % count)
                    elif isinstance(real_body, dict):
                        body_request = "    ${resp_%s}    %s    %s" % (
                            count, self.file.all_url.get(url)[1], "&{body_%s}" % count)
                except Exception as err:
                    log.error(traceback.print_exc())
                    body_request = "    #url: %s 无法找到对应的关键字，请检查并更新！" % url
                body_list.append(body_create)
                body_list.append(body_request)
                body_list.append("    Log    ${resp_%s}" % count)
                if self.team.upper() in ["TMO"]:
                    body_validate_resp = "    check_rf    ${resp_%s}    %s" % (count, result)
                else:
                    body_validate_code = "    Should Be Equal as strings    ${resp_%s['code']}    ${%s}"
                    # body_validate_success = "    %s    ${resp_%s['success']}"
                    body_validate_success = "    %s    ${resp_%s['success']}    %s"
                    body_validate_resp = "    %s    ${resp_%s[\"message\"]}    %s"
                    if isinstance(result, str):
                        body_validate_code = "    #特殊接口返回！"
                        body_validate_success = "    #返回为bytes类型的字符码。仅检查结果是否相等！"
                        body_validate_resp = "    Should Be Equal as strings    ${resp_%s}    %s" % (count, result)

                    elif status == "PASS":
                        body_validate_code = body_validate_code % (count, result['code'])
                        body_validate_success = body_validate_success % ("Should Be True", count, "")
                        try:
                            if result["message"]:
                                body_validate_resp = body_validate_resp % (
                                "Should Be Equal as strings", count, result["message"])
                            else:
                                body_validate_resp = body_validate_resp % (
                                "Should Be Equal as strings", count, '${EMPTY}')
                        except KeyError as err:
                            body_validate_resp = "    #resp中没有message，请后续自行添加！"
                            log.warning(err)
                            log.warning("resp中没有message，请后续自行添加！")
                    else:
                        try:
                            body_validate_code = body_validate_code % (count, result['code'])
                        except Exception as e:
                            if "status" in result:
                                body_validate_code = body_validate_code % (count, result['status'])
                                body_validate_code = body_validate_code.replace("code", "status")
                            else:
                                raise KeyError("接口不中无code返回，请与开发确认！！！")
                        try:
                            body_validate_success = body_validate_success % (
                            "Should Be Equal As Strings", count, result["success"])
                        except Exception as err:
                            if "error" in result:
                                body_validate_success = body_validate_success % (
                                    "Should Be Equal As Strings", count, result["error"])
                                body_validate_success = body_validate_success.replace("success", "error")
                            else:
                                raise KeyError("接口不中无success返回，请与开发确认！！！")
                        try:
                            if result.get("message"):
                                if re.search("[a-zA-Z0-9]{32}", result.get("message", "")):
                                    body_validate_resp = body_validate_resp % ("should contain", count,
                                                                               re.sub("[a-zA-Z0-9]{32}", "", result["message"]))
                                else:
                                    body_validate_resp = body_validate_resp % (
                                    "should be equal as strings", count, result["message"])
                            else:
                                body_validate_resp = body_validate_resp % (
                                "Should Be Equal as strings", count, '${EMPTY}')
                        except KeyError as err:
                            body_validate_resp = "    #resp中没有message，请后续自行添加！"
                            log.warning(err)
                            log.warning("resp中没有message，请后续自行添加！")

                    body_list.append(body_validate_code)
                    body_list.append(body_validate_success)
                body_list.append(body_validate_resp)
                # body_list.append("    #请自行添加data校验！")
                count += 1
        body_list.append("\n")
        return "\n".join(body_list)

    def _generate_body_expect_type_value(self, type):
        if type.lower() == 'integer':
            value = random.randint(0, 100)
        elif type.lower() == "string":
            value = "".join([random.choice(string.digits + string.ascii_letters) for i in range(5)])
        elif type.lower() == "date":
            value = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
        elif type.lower() == "boolean":
            value = True
        elif type.lower() == "array":
            value = [1]
        else:
            value = "123"
        return value

    def _generate_body_un_expect_type_value(self, type):
        value = ""
        if type.lower() == 'integer':
            value = "".join([random.choice(string.digits + string.ascii_letters) for i in range(5)])
        elif type.lower() == "string":
            value = random.randint(0, 10000)
        else:
            value = False
        return value

    def _analysis_dict_to_body_value(self, dict_none, dict_data):
        """
        生成所有请求参数的组合列表
        """
        data_list = []
        if isinstance(dict_none, list):
            if dict_none:
                for index in range(len(dict_none)):
                    data = self._analysis_dict_to_body_value(dict_none[index], dict_data[index])
                    data_list.extend(data)
            else:
                data_list = dict_data
        elif isinstance(dict_none, dict):
            try:
                len_num = self._get_nums(dict_data)
            except Exception as e:
                # log.error(e)
                log.error("数据表request_parameters中参数不全，请使用interface_hunter补全参数")
                raise e
            for i in range(0, len_num):
                copy_dict = copy.copy(dict_none)
                for key, value in copy_dict.items():
                    data = self._analysis_dict_to_body_value(copy_dict[key], dict_data[key])
                    if not data:
                        copy_dict[key] = None
                    elif i >= len(data):
                        copy_dict[key] = data[0]
                        if isinstance(value, list):
                            copy_dict[key] = [data[0]]
                    else:
                        copy_dict[key] = data[i]
                        if isinstance(value, list):
                            copy_dict[key] = [data[i]]

                data_list.append(copy_dict)

        else:
            data_list = dict_data

        return data_list

    def _get_nums(self, dict_data):
        """
        获取所有参数对应值的最大长度
        """
        nums_list = [0]
        if isinstance(dict_data, list):
            for item in dict_data:
                if isinstance(item, dict):
                    data = self._get_nums(dict_data[0])
                    nums_list.append(data)
            else:
                nums_list.append(len(dict_data))

        elif isinstance(dict_data, dict):
            for value in dict_data.values():
                data = self._get_nums(value)
                nums_list.append(data)
        elif dict_data == None:
            nums_list.append(0)
        else:
            nums_list.append(len(dict_data))
        return max(nums_list)

    def _analysis_case_parameters_to_value(self, interface_demo, parameters):
        """
        根据demo将每个参数的对应值的列表写回demo
        """
        body = copy.copy(interface_demo)
        if isinstance(body, list):
            for index in range(len(body)):
                item = body[index]
                body[index] = self._analysis_case_parameters_to_value(item, parameters)

        elif isinstance(body, dict):
            for key, value in body.items():
                if isinstance(value, dict) or isinstance(value, list):
                    if value:
                        body[key] = self._analysis_case_parameters_to_value(body.get(key), parameters)
                    else:
                        body[key] = parameters.get(key)
                else:
                    body[key] = parameters.get(key)
        return body

    def _analysis_case_parameters_to_dict(self, parameters):
        """
        根据所有参数生成正常值 和异常值的列表
        """
        expect_lenth = 0
        un_expect_lenth = 0
        parameter_expect_dict = dict()
        parameter_un_expect_dict = dict()
        for parameter in parameters:
            parameter_attr = SetAttr(parameter)
            if parameter_attr.normal_values:
                if parameter_attr.normal_values.startswith("["):
                    parameter_expect_dict[parameter_attr.name] = parameter_attr.normal_values.split(",")
                else:
                    if parameter_attr.type == "array":
                        parameter_expect_dict[parameter_attr.name] = [[x] for x in parameter_attr.normal_values.split(",")]
                    else:
                        parameter_expect_dict[parameter_attr.name] = parameter_attr.normal_values.split(",")
            else:
                continue
            if len(parameter_expect_dict[parameter_attr.name]) > expect_lenth:
                expect_lenth = len(parameter_expect_dict[parameter_attr.name])

            if parameter_attr.exception_values:
                parameter_un_expect_dict[parameter_attr.name] = parameter_attr.exception_values.split(",")
            else:
                # raise Exception("接口参数%s无异常值，请先确认接口参数。" % parameter_attr.name)
                parameter_un_expect_dict[parameter_attr.name] = []

            if len(parameter_un_expect_dict[parameter_attr.name]) > un_expect_lenth:
                un_expect_lenth = len(parameter_un_expect_dict[parameter_attr.name])

        return parameter_expect_dict, parameter_un_expect_dict, expect_lenth, un_expect_lenth

    def generate_case_doc(self, interface_info, tags=None, demo=None):
        if demo:
            lenth, demo_json, paras_d = self.file.kw._clean_demo_to_less_key(demo)
        doc_list = list()
        doc_list.append(
            "    [Documentation]     {}    接口路径：{}, {}".format(interface_info.interface_describe,
                                                               interface_info.type, interface_info.in_url))
        # doc_list.append(self.doc_content_row_temp.format("输入参数名", "参数类型", "说明"))
        # for parameters_info in parameters:
        #     sub_doc = self._generate_case_doc(parameters_info)
        #     doc_list.append(sub_doc)
        if tags:
            tag_list = tags.split(",")
            tag = "    [Tags]"
            for tag_ in tag_list:
                tag += "    %s" % tag_
            doc_list.append(tag)
        if lenth > 1:
            doc_list.append(
                "    # 请求参数说明    h:放header里的参数    u:放url路径节点中的参数    d:不放在url中在请求参数    p：放在url问号后在key-value结构参数")
        return "\n".join(doc_list)

    def _generate_case_doc(self, request_parameter):
        doc_content = list()
        parameter_attr = SetAttr(request_parameter)
        row = self.doc_content_row_temp.format(parameter_attr.name, parameter_attr.type, parameter_attr.note)
        doc_content.append(row)
        return "\n".join(doc_content)

    def generate_case_file_path(self, interface_info):
        path_cell_list = self._generate_case_file_path_info(interface_info.in_url)
        path_cell_list.insert(0, self.file.case_dir)
        return os.path.abspath(os.path.join(*path_cell_list[:-1]) + ".robot"), path_cell_list[-1]

    def _generate_case_file_path_info(self, url):
        head_list = []
        para_list = []
        host, url_last = re.search(r"(\S+\.cn|\S+\.com)(\S+)", url).groups()
        path_first = re.search("//([\w+\-]+)\.", host).group(1)
        head_list.append(path_first)
        search = re.findall("[\w+\-_]+|[\{\w+\-_\}]+", url_last)
        for item in search:
            if "{" in item:
                temp = item.replace("{", "").replace("}", "")
                para_list.append(temp)
            else:
                head_list.append(item)
        return head_list


def run_interface_case_generate(result_path, interface, demo_info, parameters, case_instance, tags=None, normal=None):
    case_type_list = ["1001", "1101", "1102", "1201"]
    not_exist_case_type = list()
    exist_case_name = list()
    case_path, _ = case_instance.generate_case_file_path(interface)
    case_name_head = interface.name
    if parameters:
        for case_type in case_type_list:
            case_name = "-".join([case_name_head, case_type])
            if not case_instance.file.check_case_exist(case_path, case_name):
                not_exist_case_type.append(case_type)
            else:
                exist_case_name.append(case_name)
    else:
        case_name = "-".join([case_name_head, "1001"])
        if not case_instance.file.check_case_exist(case_path, case_name):
            not_exist_case_type.append("1001")
        else:
            exist_case_name.append(case_name)
    for item in exist_case_name:
        msg = "接口url：%s,%s,已存在用例%s，请确认!" % (interface.type, interface.in_url, item)
        log.warning(msg)
        case_instance.file.write_content_to_case_file(result_path, msg + "\n")
    if not_exist_case_type:
        if normal:
            not_exist_case_type = ["1001"]
        case_instance.file.generate_case_file(case_path)
        try:
            demo = json.loads(demo_info.request_demo)
        except Exception as err:
            log.error(traceback.print_exc())
            log.warning("the demo of interface(%s) is empty,please check." % interface.id)
            demo = dict()
        try:
            result = list()
            result.append("")
            result.append("-" * 60)
            result.append("用例生成成功！")
            for case_type in not_exist_case_type:
                body = case_instance.create_case_content(result_path, interface, parameters, demo, case_type, tags=tags)
                # result.append(body)
            result.append(body.split("！")[1])
            log.info("\n".join(result))
        except:
            log.error("could not generate case for interface id: %s, url: %s" % (interface.id, interface.in_url))
            log.error(traceback.print_exc())
    else:
        msg = "接口url：%s,%s,已存在用例，请确认!" % (interface.type, interface.in_url)
        log.warning(msg)
        case_instance.file.write_content_to_case_file(result_path, msg + "\n")
