"""
描述:
- SerialiserLike 协议的单元测试。
- 测试协议的结构、实现和运行时类型检查。
"""

from __future__ import annotations

from typing import Any

from xfintech.serde.common.dataformat import DataFormat
from xfintech.serde.common.serialiserlike import SerialiserLike

# =============================================================================
# Protocol Structure Tests
# =============================================================================


def test_serialiserlike_is_protocol():
    """测试 SerialiserLike 是一个协议类"""
    from typing import Protocol

    assert issubclass(SerialiserLike.__class__, type(Protocol))


def test_serialiserlike_has_serialise_method():
    """测试 SerialiserLike 定义了 serialise 方法"""
    assert hasattr(SerialiserLike, "serialise")


def test_serialiserlike_method_signature():
    """测试 serialise 方法签名"""
    import inspect

    sig = inspect.signature(SerialiserLike.serialise)
    params = list(sig.parameters.keys())
    assert "data" in params
    assert "format" in params
    assert "kwargs" in params


# =============================================================================
# Implementation Tests - Valid Implementations
# =============================================================================


def test_valid_implementation_with_staticmethod():
    """测试使用 staticmethod 的有效实现"""

    class ValidSerialiser:
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            return b"test"

    instance = ValidSerialiser()
    assert isinstance(instance, SerialiserLike)


def test_valid_implementation_with_classmethod():
    """测试使用 classmethod 的有效实现"""

    class ValidSerialiser:
        @classmethod
        def serialise(cls, data: Any, format: Any, **kwargs: Any) -> bytes:
            return b"test"

    instance = ValidSerialiser()
    assert isinstance(instance, SerialiserLike)


def test_valid_implementation_with_instance_method():
    """测试使用实例方法的有效实现"""

    class ValidSerialiser:
        def serialise(self, data: Any, format: Any, **kwargs: Any) -> bytes:
            return b"test"

    instance = ValidSerialiser()
    assert isinstance(instance, SerialiserLike)


def test_valid_implementation_can_call_serialise():
    """测试有效实现可以调用 serialise"""

    class ValidSerialiser:
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            return b"serialized"

    serialiser = ValidSerialiser()
    result = serialiser.serialise({}, DataFormat.JSON)
    assert result == b"serialized"


def test_valid_implementation_with_kwargs():
    """测试有效实现支持 kwargs"""

    class ValidSerialiser:
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            encoding = kwargs.get("encoding", "utf-8")
            return f"encoded:{encoding}".encode()

    serialiser = ValidSerialiser()
    result = serialiser.serialise({}, DataFormat.JSON, encoding="ascii")
    assert result == b"encoded:ascii"


def test_valid_implementation_with_complex_logic():
    """测试有效实现包含复杂逻辑"""

    class ComplexSerialiser:
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            if format == DataFormat.JSON:
                import json

                return json.dumps(data).encode()
            elif format == DataFormat.CSV:
                return b"csv,data"
            else:
                return b"unknown"

    serialiser = ComplexSerialiser()
    assert isinstance(serialiser, SerialiserLike)
    result = serialiser.serialise({"key": "value"}, DataFormat.JSON)
    assert result == b'{"key": "value"}'


# =============================================================================
# Implementation Tests - Invalid Implementations
# =============================================================================


def test_invalid_implementation_missing_method():
    """测试缺少 serialise 方法的实现"""

    class InvalidSerialiser:
        pass

    instance = InvalidSerialiser()
    assert not isinstance(instance, SerialiserLike)


def test_invalid_implementation_wrong_method_name():
    """测试方法名错误的实现"""

    class InvalidSerialiser:
        @staticmethod
        def serialize(data: Any, format: Any, **kwargs: Any) -> bytes:
            return b"test"

    instance = InvalidSerialiser()
    assert not isinstance(instance, SerialiserLike)


def test_property_implementation_is_valid():
    """测试使用 property 的实现也是有效的"""

    class PropertySerialiser:
        @property
        def serialise(self):
            return lambda data, format, **kwargs: b"test"

    instance = PropertySerialiser()
    # Python's Protocol accepts properties with callable values
    assert isinstance(instance, SerialiserLike)


# =============================================================================
# Type Checking Tests
# =============================================================================


def test_isinstance_with_valid_class():
    """测试 isinstance 检查有效类"""

    class MySerialiser:
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            return b""

    assert isinstance(MySerialiser(), SerialiserLike)


def test_isinstance_with_invalid_class():
    """测试 isinstance 检查无效类"""

    class NotSerialiser:
        def other_method(self):
            pass

    assert not isinstance(NotSerialiser(), SerialiserLike)


def test_isinstance_with_builtin_types():
    """测试 isinstance 检查内置类型"""
    assert not isinstance(str(), SerialiserLike)
    assert not isinstance(int(), SerialiserLike)
    assert not isinstance(list(), SerialiserLike)
    assert not isinstance(dict(), SerialiserLike)


def test_isinstance_with_none():
    """测试 isinstance 检查 None"""
    assert not isinstance(None, SerialiserLike)


# =============================================================================
# Inheritance Tests
# =============================================================================


def test_can_inherit_from_protocol():
    """测试可以继承协议"""

    class BaseSerialiser(SerialiserLike):
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            return b"base"

    instance = BaseSerialiser()
    assert isinstance(instance, SerialiserLike)


def test_inherited_class_can_override():
    """测试继承类可以重写方法"""

    class BaseSerialiser(SerialiserLike):
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            return b"base"

    class DerivedSerialiser(BaseSerialiser):
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            return b"derived"

    derived = DerivedSerialiser()
    assert isinstance(derived, SerialiserLike)
    assert derived.serialise({}, DataFormat.JSON) == b"derived"


# =============================================================================
# Edge Cases Tests
# =============================================================================


def test_implementation_with_default_arguments():
    """测试带默认参数的实现"""

    class SerialiserWithDefaults:
        @staticmethod
        def serialise(data: Any, format: Any = DataFormat.JSON, **kwargs: Any) -> bytes:
            return b"default"

    serialiser = SerialiserWithDefaults()
    assert isinstance(serialiser, SerialiserLike)


def test_implementation_with_extra_methods():
    """测试包含额外方法的实现"""

    class RichSerialiser:
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            return b"test"

        @staticmethod
        def validate(data: Any) -> bool:
            return True

    serialiser = RichSerialiser()
    assert isinstance(serialiser, SerialiserLike)


def test_implementation_with_attributes():
    """测试包含属性的实现"""

    class SerialiserWithState:
        def __init__(self):
            self.counter = 0

        def serialise(self, data: Any, format: Any, **kwargs: Any) -> bytes:
            self.counter += 1
            return b"test"

    serialiser = SerialiserWithState()
    assert isinstance(serialiser, SerialiserLike)


def test_callable_object_as_implementation():
    """测试可调用对象作为实现"""

    class CallableSerialiser:
        def serialise(self, data: Any, format: Any, **kwargs: Any) -> bytes:
            return b"callable"

    instance = CallableSerialiser()
    assert isinstance(instance, SerialiserLike)


# =============================================================================
# Real-World Usage Tests
# =============================================================================


def test_parquet_serialiser_implementation():
    """测试 Parquet 序列化器实现"""

    class ParquetSerialiser:
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            if format != DataFormat.PARQUET:
                raise ValueError(f"Unsupported format: {format}")
            # Simulate parquet serialization
            return b"parquet_data"

    serialiser = ParquetSerialiser()
    assert isinstance(serialiser, SerialiserLike)
    result = serialiser.serialise({}, DataFormat.PARQUET)
    assert result == b"parquet_data"


def test_csv_serialiser_implementation():
    """测试 CSV 序列化器实现"""

    class CSVSerialiser:
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            if format != DataFormat.CSV:
                raise ValueError(f"Unsupported format: {format}")
            # Simulate CSV serialization
            return b"col1,col2\nval1,val2"

    serialiser = CSVSerialiser()
    assert isinstance(serialiser, SerialiserLike)
    result = serialiser.serialise({}, DataFormat.CSV)
    assert result == b"col1,col2\nval1,val2"


def test_json_serialiser_implementation():
    """测试 JSON 序列化器实现"""
    import json

    class JSONSerialiser:
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            if format != DataFormat.JSON:
                raise ValueError(f"Unsupported format: {format}")
            return json.dumps(data).encode("utf-8")

    serialiser = JSONSerialiser()
    assert isinstance(serialiser, SerialiserLike)
    result = serialiser.serialise({"test": 123}, DataFormat.JSON)
    assert result == b'{"test": 123}'


def test_multi_format_serialiser():
    """测试多格式序列化器"""
    import json

    class MultiFormatSerialiser:
        @staticmethod
        def serialise(data: Any, format: Any, **kwargs: Any) -> bytes:
            if format == DataFormat.JSON:
                return json.dumps(data).encode("utf-8")
            elif format == DataFormat.CSV:
                return b"csv_data"
            elif format == DataFormat.PARQUET:
                return b"parquet_data"
            else:
                raise ValueError(f"Unsupported format: {format}")

    serialiser = MultiFormatSerialiser()
    assert isinstance(serialiser, SerialiserLike)

    # Test each format
    json_result = serialiser.serialise({"key": "value"}, DataFormat.JSON)
    assert json_result == b'{"key": "value"}'

    csv_result = serialiser.serialise({}, DataFormat.CSV)
    assert csv_result == b"csv_data"

    parquet_result = serialiser.serialise({}, DataFormat.PARQUET)
    assert parquet_result == b"parquet_data"


# =============================================================================
# Protocol Attribute Tests
# =============================================================================


def test_protocol_module():
    """测试协议所属模块"""
    assert SerialiserLike.__module__ == "xfintech.serde.common.serialiserlike"


def test_protocol_name():
    """测试协议名称"""
    assert SerialiserLike.__name__ == "SerialiserLike"
