"""Tests for CitationRecord.from_citation_result() factory method"""
import uuid

import pytest

from app.models.citation_record import CitationRecord


class TestFromCitationResultBasicFields:
    """基本字段映射"""

    def test_basic_fields_mapped(self):
        query_id = uuid.uuid4()
        result = {
            "cited": True,
            "position": 2,
            "citation_text": "Brand X is recommended",
            "competitor_brands": ["Brand Y", "Brand Z"],
            "raw_response": "Some raw response",
            "confidence": 0.95,
            "match_type": "direct",
        }
        record = CitationRecord.from_citation_result(
            query_id=query_id,
            platform="kimi",
            result=result,
        )
        assert record.query_id == query_id
        assert record.platform == "kimi"
        assert record.cited is True
        assert record.citation_position == 2
        assert record.citation_text == "Brand X is recommended"
        assert record.competitor_brands == ["Brand Y", "Brand Z"]
        assert record.confidence == 0.95
        assert record.match_type == "direct"

    def test_missing_optional_fields_use_defaults(self):
        query_id = uuid.uuid4()
        result = {"cited": False}
        record = CitationRecord.from_citation_result(
            query_id=query_id,
            platform="wenxin",
            result=result,
        )
        assert record.cited is False
        assert record.citation_position is None
        assert record.citation_text is None
        assert record.competitor_brands == []
        assert record.raw_response == ""
        assert record.confidence is None
        assert record.match_type is None


class TestFromCitationResultSourceFields:
    """引用源分析字段"""

    def test_source_fields_populated(self):
        query_id = uuid.uuid4()
        result = {
            "cited": True,
            "data_source": "ai_platform",
            "source_urls": ["https://example.com"],
            "source_titles": ["Example Title"],
            "citation_contexts": ["context snippet"],
            "ai_response_text": "AI said something",
        }
        record = CitationRecord.from_citation_result(
            query_id=query_id,
            platform="kimi",
            result=result,
        )
        assert record.data_source == "ai_platform"
        assert record.source_urls == ["https://example.com"]
        assert record.source_titles == ["Example Title"]
        assert record.citation_contexts == ["context snippet"]
        assert record.ai_response_text == "AI said something"

    def test_source_fields_default_to_none(self):
        query_id = uuid.uuid4()
        result = {"cited": False}
        record = CitationRecord.from_citation_result(
            query_id=query_id,
            platform="kimi",
            result=result,
        )
        assert record.data_source is None
        assert record.source_urls is None
        assert record.source_titles is None
        assert record.citation_contexts is None
        assert record.ai_response_text == ""


class TestFromCitationResultSanitization:
    """raw_response 和 ai_response_text 应该被清理"""

    def test_raw_response_sanitized(self):
        query_id = uuid.uuid4()
        result = {
            "cited": True,
            "raw_response": "Hello\x00World\x08!",
        }
        record = CitationRecord.from_citation_result(
            query_id=query_id,
            platform="kimi",
            result=result,
        )
        # NULL 字节和 \x08 应该被移除
        assert "\x00" not in record.raw_response
        assert "\x08" not in record.raw_response
        assert "Hello" in record.raw_response
        assert "World" in record.raw_response

    def test_ai_response_text_sanitized(self):
        query_id = uuid.uuid4()
        result = {
            "cited": True,
            "ai_response_text": "Text\x00with\x0bcontrol\x1fchars",
        }
        record = CitationRecord.from_citation_result(
            query_id=query_id,
            platform="kimi",
            result=result,
        )
        assert "\x00" not in record.ai_response_text
        assert "\x0b" not in record.ai_response_text
        assert "\x1f" not in record.ai_response_text

    def test_newline_preserved_in_sanitization(self):
        query_id = uuid.uuid4()
        result = {
            "cited": True,
            "raw_response": "Line1\nLine2\tTab\rReturn",
        }
        record = CitationRecord.from_citation_result(
            query_id=query_id,
            platform="kimi",
            result=result,
        )
        assert "\n" in record.raw_response
        assert "\t" in record.raw_response
        assert "\r" in record.raw_response

    def test_none_raw_response_becomes_empty_string(self):
        query_id = uuid.uuid4()
        result = {"cited": True, "raw_response": None}
        record = CitationRecord.from_citation_result(
            query_id=query_id,
            platform="kimi",
            result=result,
        )
        assert record.raw_response == ""
