"""
测试：DualEngine 双引擎模式
"""
import pytest
import sys
sys.path.insert(0, "src")

from playwright_ez import EasyBrowser, Config, DualEngine, DualEngineResponse


class TestDualEngine:
    """测试 DualEngine 双引擎模式"""

    @pytest.mark.asyncio
    async def test_dual_engine_creation(self):
        """测试创建 DualEngine"""
        async with EasyBrowser() as browser:
            engine = DualEngine(browser)

            assert engine.browser is not None

    @pytest.mark.asyncio
    async def test_get_requests_mode(self):
        """测试使用 requests 模式 GET 请求"""
        async with EasyBrowser() as browser:
            engine = DualEngine(browser)

            # 强制使用 requests 模式
            response = await engine.get(
                "https://httpbin.org/get",
                mode="requests",
                timeout=15.0,
            )

            assert isinstance(response, DualEngineResponse)
            assert response.status_code == 200
            assert response.mode == "requests"
            assert response.json_data is not None
            assert response.json_data.get("url") == "https://httpbin.org/get"

    @pytest.mark.asyncio
    async def test_get_browser_mode(self):
        """测试使用浏览器模式 GET 请求"""
        async with EasyBrowser() as browser:
            engine = DualEngine(browser)

            # 强制使用浏览器模式
            response = await engine.get(
                "https://example.com",
                mode="browser",
                timeout=15.0,
            )

            assert isinstance(response, DualEngineResponse)
            assert response.status_code == 200
            assert response.mode == "browser"

    @pytest.mark.asyncio
    async def test_post_requests_mode(self):
        """测试使用 requests 模式 POST 请求"""
        async with EasyBrowser() as browser:
            engine = DualEngine(browser)

            response = await engine.post(
                "https://httpbin.org/post",
                mode="requests",
                json={"test": "data"},
                timeout=15.0,
            )

            assert response.status_code == 200
            assert response.mode == "requests"

            # 验证请求数据
            json_data = response.json_data
            assert json_data.get("json", {}).get("test") == "data"

    @pytest.mark.asyncio
    async def test_auto_mode_static_url(self):
        """测试自动模式判断静态 URL"""
        async with EasyBrowser() as browser:
            engine = DualEngine(browser)

            # JSON API 应该自动使用 requests
            response = await engine.get(
                "https://httpbin.org/json",
                mode="auto",
                timeout=15.0,
            )

            assert response.status_code == 200
            # 由于是 /json 路径，应该使用 requests
            assert response.mode == "requests"

    @pytest.mark.asyncio
    async def test_response_properties(self):
        """测试响应对象属性"""
        async with EasyBrowser() as browser:
            engine = DualEngine(browser)

            response = await engine.get(
                "https://httpbin.org/get",
                mode="requests",
                timeout=15.0,
            )

            # 测试属性
            assert response.url == "https://httpbin.org/get"
            assert response.status_code == 200
            assert isinstance(response.headers, dict)
            assert len(response.content) > 0
            assert len(response.text) > 0
            assert response.elapsed > 0

    @pytest.mark.asyncio
    async def test_response_json_method(self):
        """测试响应 json() 方法"""
        async with EasyBrowser() as browser:
            engine = DualEngine(browser)

            response = await engine.get(
                "https://httpbin.org/json",
                mode="requests",
                timeout=15.0,
            )

            json_data = response.json()

            assert json_data is not None
            assert "slideshow" in json_data


class TestDualEngineModeDetection:
    """测试双引擎模式检测"""

    @pytest.fixture
    def engine(self):
        """创建引擎实例"""
        return DualEngine()

    def test_determine_mode_api_url(self, engine):
        """测试 API URL 检测"""
        mode = engine._determine_mode("https://api.example.com/users")
        assert mode == "requests"

    def test_determine_mode_json_url(self, engine):
        """测试 JSON URL 检测"""
        mode = engine._determine_mode("https://example.com/data.json")
        assert mode == "requests"

    def test_determine_mode_spa_path(self, engine):
        """测试 SPA 路径检测"""
        mode = engine._determine_mode("https://example.com/app/dashboard")
        assert mode == "browser"

    def test_determine_mode_static_extension(self, engine):
        """测试静态扩展名检测"""
        mode = engine._determine_mode("https://example.com/data.xml")
        assert mode == "requests"

        mode = engine._determine_mode("https://example.com/data.csv")
        assert mode == "requests"

    def test_set_url_type(self, engine):
        """测试手动设置 URL 类型"""
        engine.set_url_type("https://custom.example.com", "browser")

        mode = engine._determine_mode("https://custom.example.com")
        assert mode == "browser"

    def test_clear_cache(self, engine):
        """测试清空缓存"""
        engine.set_url_type("https://test.example.com", "browser")
        assert len(engine._url_type_cache) > 0

        engine.clear_cache()
        assert len(engine._url_type_cache) == 0


class TestDualEngineCookies:
    """测试双引擎 Cookie 同步"""

    @pytest.mark.asyncio
    async def test_sync_cookies_to_browser(self):
        """测试同步 Cookie 到浏览器"""
        async with EasyBrowser() as browser:
            engine = DualEngine(browser)

            # 先用 requests 获取一些 cookies
            await engine.get(
                "https://httpbin.org/cookies/set/test_cookie/test_value",
                mode="requests",
                timeout=15.0,
            )

            # 同步到浏览器
            await engine.sync_cookies_to_browser()

            # 验证同步成功（不抛出异常）
            assert True

    @pytest.mark.asyncio
    async def test_sync_cookies_to_requests(self):
        """测试同步 Cookie 到 requests"""
        async with EasyBrowser() as browser:
            engine = DualEngine(browser)

            # 先在浏览器中设置 cookies
            await browser.goto("https://example.com")
            await browser.cookies.set_cookies([{
                "name": "browser_cookie",
                "value": "browser_value",
                "domain": "example.com",
                "path": "/",
            }])

            # 同步到 requests
            await engine.sync_cookies_to_requests()

            # 验证 requests session 有该 cookie
            assert "browser_cookie" in engine.requests_session.cookies


class TestDualEngineStats:
    """测试双引擎统计"""

    @pytest.mark.asyncio
    async def test_get_stats(self):
        """测试获取统计信息"""
        async with EasyBrowser() as browser:
            engine = DualEngine(browser)

            # 进行一些请求
            engine.set_url_type("https://test1.example.com", "requests")
            engine.set_url_type("https://test2.example.com", "browser")

            stats = engine.get_stats()

            assert stats["cached_urls"] == 2
            assert stats["requests_mode_count"] == 1
            assert stats["browser_mode_count"] == 1
            assert stats["has_browser"] is True
            assert stats["has_requests_session"] is True


class TestDualEngineContext:
    """测试 DualEngineContext 上下文管理器"""

    @pytest.mark.asyncio
    async def test_context_manager(self):
        """测试上下文管理器自动管理"""
        async with DualEngineContext() as engine:
            assert engine.browser is not None

            response = await engine.get(
                "https://example.com",
                mode="browser",
                timeout=15.0,
            )

            assert response.status_code == 200

        # 退出后浏览器应该关闭


if __name__ == "__main__":
    pytest.main([__file__, "-v"])
