"""
测试基类功能: BaseMemoryWorkbook 和相关混入类
"""

import pytest

from src.symphra_excel.base import BaseMemoryWorkbook, WorkbookOperationsMixin
from src.symphra_excel.memory_ops import InMemoryWorkbook, MemoryOptimizedWorkbook
from src.symphra_excel.utils.memory_manager import MemoryManager, MemoryStrategy


class TestBaseMemoryWorkbook:
    """测试BaseMemoryWorkbook抽象基类"""

    def test_cannot_instantiate_directly(self):
        """测试无法直接实例化抽象基类"""
        with pytest.raises(TypeError, match="Can't instantiate abstract class"):
            BaseMemoryWorkbook()

    def test_memory_manager_property(self):
        """测试memory_manager属性"""
        wb = InMemoryWorkbook()
        assert isinstance(wb.memory_manager, MemoryManager)
        assert wb.memory_manager.strategy == MemoryStrategy.MEMORY_ONLY

    def test_context_manager_protocol(self):
        """测试上下文管理器协议"""
        with InMemoryWorkbook() as wb:
            assert isinstance(wb, InMemoryWorkbook)
            wb.create_worksheet("Test")
        # 上下文退出后应该调用了cleanup

    def test_get_memory_usage_base_stats(self):
        """测试基础内存统计"""
        wb = InMemoryWorkbook()
        stats = wb.get_memory_usage()

        # 验证基础统计字段
        assert "memory_strategy" in stats
        assert "registered_objects" in stats
        assert "cache_entries" in stats
        assert "memory_usage_mb" in stats

        # 验证子类扩展的字段
        assert "total_size" in stats
        assert "sheet_count" in stats

    def test_optimize_memory(self):
        """测试内存优化"""
        wb = InMemoryWorkbook()
        result = wb.optimize_memory()

        assert isinstance(result, dict)
        assert "before_mb" in result
        assert "after_mb" in result
        assert "gc_performed" in result


class TestInMemoryWorkbookInheritance:
    """测试InMemoryWorkbook的继承实现"""

    def test_inherits_from_base(self):
        """测试正确继承自BaseMemoryWorkbook"""
        wb = InMemoryWorkbook()
        assert isinstance(wb, BaseMemoryWorkbook)
        assert isinstance(wb, WorkbookOperationsMixin)

    def test_cleanup_implementation(self):
        """测试cleanup方法实现"""
        wb = InMemoryWorkbook()
        # cleanup应该不抛出异常
        wb.cleanup()

    def test_default_strategy(self):
        """测试默认策略为MEMORY_ONLY"""
        wb = InMemoryWorkbook()
        assert wb.memory_manager.strategy == MemoryStrategy.MEMORY_ONLY

    def test_custom_memory_manager(self):
        """测试自定义内存管理器"""
        custom_mm = MemoryManager()
        custom_mm.set_strategy(MemoryStrategy.BATCHED)

        wb = InMemoryWorkbook(memory_manager=custom_mm)
        assert wb.memory_manager is custom_mm
        assert wb.memory_manager.strategy == MemoryStrategy.BATCHED

    def test_get_sheet_names_from_mixin(self):
        """测试从混入类继承的get_sheet_names方法"""
        wb = InMemoryWorkbook()
        wb.create_worksheet("Sheet2")

        names = wb.get_sheet_names()
        assert isinstance(names, list)
        assert len(names) >= 1


class TestMemoryOptimizedWorkbookInheritance:
    """测试MemoryOptimizedWorkbook的继承实现"""

    def test_inherits_from_base(self):
        """测试正确继承自BaseMemoryWorkbook"""
        wb = MemoryOptimizedWorkbook()
        assert isinstance(wb, BaseMemoryWorkbook)

    def test_cleanup_implementation(self):
        """测试cleanup方法实现(调用workbook.close)"""
        wb = MemoryOptimizedWorkbook()
        # cleanup应该不抛出异常
        wb.cleanup()

    def test_default_strategy(self):
        """测试默认策略为STREAMING"""
        wb = MemoryOptimizedWorkbook()
        assert wb.memory_manager.strategy == MemoryStrategy.STREAMING

    def test_context_manager(self):
        """测试上下文管理器"""
        with MemoryOptimizedWorkbook() as wb:
            assert isinstance(wb, MemoryOptimizedWorkbook)
        # 上下文退出后应该调用了cleanup和workbook.close


class TestWorkbookOperationsMixin:
    """测试WorkbookOperationsMixin混入类"""

    def test_get_sheet_names_requires_workbook(self):
        """测试get_sheet_names需要_workbook属性"""

        class DummyClass(WorkbookOperationsMixin):
            pass

        obj = DummyClass()
        with pytest.raises(AttributeError, match="_workbook 未初始化"):
            obj.get_sheet_names()

    def test_get_sheet_names_works_with_workbook(self):
        """测试有_workbook时get_sheet_names正常工作"""
        wb = InMemoryWorkbook()
        names = wb.get_sheet_names()
        assert isinstance(names, list)
        assert len(names) >= 1  # 至少有一个默认工作表


class TestInheritanceChain:
    """测试继承链的正确性"""

    def test_inmemory_workbook_mro(self):
        """测试InMemoryWorkbook的方法解析顺序"""
        mro = InMemoryWorkbook.__mro__

        # 验证继承顺序
        assert BaseMemoryWorkbook in mro
        assert WorkbookOperationsMixin in mro
        assert object in mro

    def test_memory_optimized_workbook_mro(self):
        """测试MemoryOptimizedWorkbook的方法解析顺序"""
        mro = MemoryOptimizedWorkbook.__mro__

        # 验证继承顺序
        assert BaseMemoryWorkbook in mro
        assert object in mro

    def test_method_resolution_order(self):
        """测试方法解析顺序正确"""
        wb = InMemoryWorkbook()

        # __enter__ 和 __exit__ 来自 BaseMemoryWorkbook
        assert hasattr(wb, "__enter__")
        assert hasattr(wb, "__exit__")

        # cleanup 来自子类实现
        assert hasattr(wb, "cleanup")

        # get_sheet_names 来自 WorkbookOperationsMixin
        assert hasattr(wb, "get_sheet_names")
