# -*- coding: utf-8 -*-
"""
@Time : 2025/7/30 10:58
@Auth : 九月的海
@File : conftest.py.py
@IDE : PyCharm
@Motto : Catch as catch can....
"""

import re
import json
import ast
import os
from pathlib import Path
import uuid
from urllib.parse import urlparse

import yaml


def parse_cookies(cookie_str):
    """解析cookies字符串为字典"""
    cookies = {}
    if not cookie_str:
        return cookies

    items = cookie_str.split(';')
    for item in items:
        item = item.strip()
        if '=' in item:
            key, value = item.split('=', 1)
            cookies[key.strip()] = value.strip()
    return cookies


class CurlConverter:
    @staticmethod
    def parse_curl(curl_command):
        """解析cURL命令返回请求组件"""
        # 方法解析
        method = re.findall(r'-X\s+(\w+)', curl_command) or re.findall(r'--request\s+(\w+)', curl_command)

        # URL解析
        url_match = re.search(r"'(https?://[^']+)'|(https?://\S+)", curl_command)

        # 头部解析
        headers = dict(re.findall(r"-H\s+'([^:]+):\s*([^']+)'", curl_command))

        # 数据处理
        data_match = re.search(r"--data-raw\s+'(.*?)'", curl_command, re.DOTALL)   # or \
                     # re.search(r"--data\s+'(.*?)'", curl_command, re.DOTALL) or \
                     # re.search(r"-d\s+'(.*?)'", curl_command, re.DOTALL)

        # Cookie解析 (新增部分)
        cookie_match = re.search(r"-b\s+'([^']+)'", curl_command) or \
                       re.search(r"--cookie\s+'([^']+)'", curl_command)

        data = None
        if data_match:
            data_str = data_match.group(1).strip()
            if data_str.startswith("{") or data_str.startswith("["):
                try:
                    data = json.loads(data_str)
                    # 处理 conditions 字段（它实际上是字符串形式的 JSON）
                    # if isinstance(data.get('conditions'), str):
                    #     try:
                    #         # 第二次解析：将字符串值转为真正的 JSON
                    #         print(22222222222222)
                    #         data['conditions'] = json.loads(data['conditions'])
                    #     except json.JSONDecodeError:
                    #         # 处理可能的解析错误
                    #         pass
                except json.JSONDecodeError as e:
                    print(e)
                    # 尝试Python dict解析
                    try:
                        data = ast.literal_eval(data_str)
                    except (SyntaxError, ValueError):
                        # 保留原始字符串
                        data = data_str
            else:
                data = data_str

        # 解析Cookies
        cookies = {}
        if cookie_match:
            cookies = parse_cookies(cookie_match.group(1))

        return {
            "method": method[0] if method else "GET",
            "url": url_match.group(0).strip("'") if url_match else "",
            "headers": headers,
            "body": data,
            "cookies": cookies  # 新增的cookies字段
        }

    @staticmethod
    def generate_test_case(curl_command, test_name="GeneratedTestCase"):
        """生成测试用例和测试数据"""
        # 解析cURL命令
        components = CurlConverter.parse_curl(curl_command)
        URL = components["url"]
        uri = urlparse(URL).path
        # 生成唯一标识
        # test_id = str(uuid.uuid4())[:8]
        # safe_test_name = test_name.replace(" ", "_").lower()
        # test_case_name = f"test_{safe_test_name}_{test_id}"
        test_case_name = "test_" + uri.lstrip('/').replace('/', '_')

        # 创建测试数据
        test_data = {
            "test_name": test_name,
            "method": components["method"],
            "url": components["url"],
            "headers": components.get("headers", {}),
            "cookies": components.get("cookies", {}),  # 新增cookies字段
            "body": components.get("body"),
            "expected": {
                "status_code": 200
            }
        }
        print(components.get("body"))

        # 创建文件路径
        base_dir = Path(__file__).parents[1]
        data_path = base_dir / "testdata" / f"{test_case_name}.yaml"
        case_path = base_dir / "testcases" / f"{test_case_name}.py"

        # 确保目录存在
        data_path.parent.mkdir(parents=True, exist_ok=True)
        case_path.parent.mkdir(parents=True, exist_ok=True)

        # 写入测试数据文件（UTF-8编码）
        with open(data_path, "w", encoding="utf-8") as f:
            yaml.dump([test_data], f, sort_keys=False, allow_unicode=True)

        # 生成测试用例模板（包含cookies处理）
        test_case_template = f'''# -*- coding: utf-8 -*-
import pytest
import json
import os
import allure
from pathlib import Path
from api_auto_framework.core.request_wrapper import RequestWrapper
from api_auto_framework.utils.data_loader import load_test_data
from api_auto_framework.utils.assertion_tools import cookie
from api_auto_framework.utils.handle_path import testData_path


# 文件路径
TEST_DATA = Path(testData_path) / f"{test_case_name}.yaml"


@allure.feature("百度")
@allure.story("媒体账户")
@allure.title("{test_name}")
@allure.severity(allure.severity_level.NORMAL)
@pytest.mark.generated
def {test_case_name}():
    """Automatically generated test case: {test_name}"""
    # 加载测试数据
    test_data = load_test_data(TEST_DATA)[0]
    # 准备请求参数
    request_kwargs = {{
        "method": test_data['method'],
        "url": test_data['url'],
        "headers": test_data.get('headers'),
        "cookies": cookie()  # 新增cookies参数
    }}
    # 智能选择请求体处理方式
    body = test_data.get('body')
    if body is not None:
        if isinstance(body, (dict, list)):
            request_kwargs["json"] = body
        else:
            request_kwargs["data"] = body
    with allure.step("准备请求数据"):
        allure.attach(f"URL: {URL}", "请求URL")
        allure.attach(json.dumps(body), "请求体", allure.attachment_type.JSON)
    # 发送请求并获取响应
    with allure.step(f"发送请求:{test_case_name}"):
        response = RequestWrapper.send_request(**request_kwargs)
        if response.status_code != 200:
            error_msg = f"请求失败，状态码: {{response.status_code}}"
            allure.attach(error_msg, "请求错误", allure.attachment_type.TEXT)
            pytest.fail(error_msg)
    with allure.step("处理请求"):
        try:
            result = RequestWrapper.formatted_response(response)
        except Exception as e:
            error_msg = f"响应处理失败: {{str(e)}}"
            allure.attach(error_msg, "响应处理错误", allure.attachment_type.TEXT)
            allure.attach(response.text, "原始响应内容", allure.attachment_type.TEXT)
            pytest.fail(error_msg)
    with allure.step("响应结果"):
        allure.attach(str(response.status_code), "响应状态", allure.attachment_type.TEXT)
        if result and "body" in result and "code" in result["body"]:
            allure.attach(str(result["body"]["code"]), "响应状态码", allure.attachment_type.TEXT)
        if result and "headers" in result:
            allure.attach(json.dumps(result["headers"], indent=2),
                          "响应头", allure.attachment_type.JSON)
        if result and "body" in result:
            body_content = result["body"]
            if isinstance(body_content, dict):
                body_str = json.dumps(body_content, indent=2, ensure_ascii=False)
            else:
                body_str = str(body_content)
            allure.attach(body_str, "响应内容", allure.attachment_type.JSON)

    # 基础状态码断言
    try:
        assert result["status_code"] == test_data["expected"]["status_code"], f"状态码不匹配: {{result['status_code']}} ≠ {{test_data['expected']['status_code']}}"
        assert result["body"]["code"] == 0, f"业务码非零: {{result['body']['code']}}"
        assert result["body"]["message"] == "成功", f"消息不符: {{result['body']['message']}}"
    except AssertionError as e:
        allure.attach(str(e), "断言失败详情", allure.attachment_type.TEXT)
        raise
    except KeyError as e:
        error_msg = f"响应体中缺少关键字段: {{str(e)}}"
        allure.attach(error_msg, "响应体结构错误", allure.attachment_type.TEXT)
        pytest.fail(error_msg)
'''

        # 用UTF-8编码写入测试用例文件
        with open(case_path, "w", encoding="utf-8") as f:
            f.write(test_case_template)
        print(case_path)
        print(data_path)
        return str(case_path), str(data_path)
