#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称：test_curl_parser.py
模块描述：curl 命令解析器 parse_curl() 单元测试

作者：czj
创建日期：2026-08-19
"""

import pytest

from app.utils.curl_parser import parse_curl


def test_parse_standard_post():
    """标准 POST 请求解析方法、请求头和 JSON body。"""
    result = parse_curl(
        "curl -X POST https://example.com/api "
        '-H "Content-Type: application/json" -d \'{"key":"val"}\''
    )

    assert result.method == "POST"
    assert result.target_url == "https://example.com/api"
    assert result.headers == {"Content-Type": "application/json"}
    assert result.body == {"key": "val"}
    assert result.auth_required is False
    assert result.sign_request is False
    assert result.errors == []


def test_parse_get_is_inferred_without_body():
    """没有 body 且未指定方法时推断为 GET。"""
    result = parse_curl("curl https://example.com/api/users")

    assert result.method == "GET"
    assert result.body is None


def test_parse_post_is_inferred_with_body():
    """没有 -X 但存在 body 时推断为 POST。"""
    result = parse_curl('curl https://example.com/api -d "name=test"')

    assert result.method == "POST"


def test_parse_authorization_is_removed_and_auth_required_is_set():
    """Authorization 头被剥离，同时启用认证标记。"""
    result = parse_curl(
        'curl -X GET https://example.com/api '
        '-H "Authorization: Bearer token123"'
    )

    assert result.auth_required is True
    assert "Authorization" not in result.headers


def test_parse_signature_headers_are_removed_and_sign_request_is_set():
    """签名相关请求头被剥离，同时启用签名标记。"""
    result = parse_curl(
        'curl -X POST https://e.com/api '
        '-H "X-SIGN: sig" -H "X-RANDOM: r" -H "X-TIMESTAMP: t" -d "{}"'
    )

    assert result.sign_request is True
    assert "X-SIGN" not in result.headers
    assert "X-RANDOM" not in result.headers
    assert "X-TIMESTAMP" not in result.headers


def test_parse_cookie_is_retained_in_headers_and_cookie_field():
    """Cookie 同时保留在请求头和 cookie 字段中。"""
    result = parse_curl('curl https://e.com -H "Cookie: sid=abc"')

    assert result.cookie == "sid=abc"
    assert result.headers["Cookie"] == "sid=abc"


def test_parse_unsupported_parameter_reports_error():
    """不支持的 -F 参数被记录到 errors。"""
    result = parse_curl('curl -F "file=@a" https://e.com')

    assert result.errors


def test_parse_inline_long_option_assignments():
    """支持长选项的内联赋值形式。"""
    result = parse_curl(
        'curl --request=POST --header="Content-Type: application/json" '
        "--data-raw='{\"x\":1}' https://e.com/api"
    )

    assert result.method == "POST"
    assert result.headers == {"Content-Type": "application/json"}
    assert result.body == {"x": 1}


def test_parse_empty_command_raises_value_error():
    """空命令抛出 ValueError。"""
    with pytest.raises(ValueError):
        parse_curl("")


def test_parse_command_without_url_raises_value_error():
    """没有 URL 的命令抛出 ValueError。"""
    with pytest.raises(ValueError):
        parse_curl("curl -X GET")


def test_parse_multiple_data_options_are_concatenated():
    """多个 -d 参数按 curl 语义以 & 拼接。"""
    result = parse_curl('curl -d "a=1" -d "b=2" https://e.com/api')

    assert result.body == "a=1&b=2"


def test_parse_cookie_flag_b():
    """-b/--cookie 旗标正确处理。"""
    result = parse_curl('curl -b "token=abc; user=1" https://e.com/api')

    assert result.cookie == "token=abc; user=1"
    assert result.headers["Cookie"] == "token=abc; user=1"


def test_parse_cookie_flag_long_option():
    """--cookie 长选项形式。"""
    result = parse_curl('curl --cookie "session=xyz" https://e.com/api')

    assert result.cookie == "session=xyz"


def test_parse_windows_cmd_caret_style():
    """
    Windows CMD 风格：^ 行尾续行符 + ^" 转义引号。
    这是用户从 CMD 直接粘贴的原始 curl 命令主题。
    """
    cmd = (
        'curl ^"https://example.com/api^" ^\n'
        '  -H ^"Content-Type: application/json^" ^\n'
        '  -H ^"Authorization: Bearer tok123^" ^\n'
        '  -H ^"X-RANDOM: rnd^" ^\n'
        '  -b ^"sid=abc^" ^\n'
        '  --insecure'
    )
    result = parse_curl(cmd)

    assert result.method == "GET"
    assert result.target_url == "https://example.com/api"
    assert result.headers == {"Content-Type": "application/json", "Cookie": "sid=abc"}
    assert result.auth_required is True
    assert result.sign_request is True
    assert result.cookie == "sid=abc"


def test_parse_windows_cmd_with_body():
    """Windows CMD 风格带 body 的 POST 请求（Chrome 生成的 \\^" 嵌套引号形式）。"""
    cmd = (
        'curl -X POST ^"https://e.com/api^" ^\n'
        '  -H ^"Content-Type: application/json^" ^\n'
        '  -d ^"{\\^"key\\^":\\^"val\\^"}^" ^\n'
        '  --insecure'
    )
    result = parse_curl(cmd)

    assert result.method == "POST"
    assert result.target_url == "https://e.com/api"
    assert result.headers == {"Content-Type": "application/json"}
    assert result.body == {"key": "val"}
