"""Tests for browser operations."""

import os
import pytest
from grasp import Grasp, AsyncGrasp

# Try to import playwright for integration tests
try:
    from playwright.sync_api import sync_playwright
    from playwright.async_api import async_playwright
    PLAYWRIGHT_AVAILABLE = True
except ImportError:
    PLAYWRIGHT_AVAILABLE = False


class TestBrowser:
    """Test browser operations."""

    def setup_method(self, method):
        """Setup before each test method."""
        self.grasp = Grasp(
            api_key=os.environ["GRASP_API_KEY"],
            base_url=os.environ["GRASP_BASE_URL"],
        )
        self.container = self.grasp.create()

    def teardown_method(self, method):
        """Cleanup after each test method."""
        if self.container:
            try:
                self.container.shutdown()
            except Exception:
                pass

    def test_valid_ws_endpoint(self):
        """Test that wsEndpoint is valid."""
        assert self.container.browser.ws_endpoint is not None
        assert self.container.browser.ws_endpoint.startswith(("ws://", "wss://"))

    def test_valid_live_url(self):
        """Test that liveURL is valid."""
        assert self.container.browser.live_url is not None
        assert self.container.browser.live_url.startswith(("http://", "https://"))

    @pytest.mark.skipif(not PLAYWRIGHT_AVAILABLE, reason="Playwright not installed")
    def test_connect_via_playwright(self):
        """Test connecting to browser via Playwright."""
        with sync_playwright() as p:
            browser = p.chromium.connect_over_cdp(
                endpoint_url=self.container.browser.ws_endpoint
            )

            assert browser is not None
            assert browser.is_connected()

            browser.close()

    @pytest.mark.skipif(not PLAYWRIGHT_AVAILABLE, reason="Playwright not installed")
    def test_navigate_and_scrape_content(self):
        """Test navigating to a page and scraping content."""
        with sync_playwright() as p:
            browser = p.chromium.connect_over_cdp(
                endpoint_url=self.container.browser.ws_endpoint
            )

            context = browser.new_context()
            page = context.new_page()

            page.goto("https://getgrasp.ai")

            title = page.title()
            url = page.url

            assert title is not None
            assert isinstance(title, str)
            assert url == "https://getgrasp.ai/"

            context.close()
            browser.close()

    def test_serialize_browser_session(self):
        """Test browser session serialization."""
        browser_serialized = self.container.browser.to_dict()

        assert browser_serialized is not None
        assert browser_serialized["ws_endpoint"] == self.container.browser.ws_endpoint
        assert browser_serialized["live_url"] == self.container.browser.live_url


@pytest.mark.asyncio
class TestAsyncBrowser:
    """Test async browser operations."""

    def setup_method(self, method):
        """Setup before each test method."""
        self.grasp = AsyncGrasp(
            api_key=os.environ["GRASP_API_KEY"],
            base_url=os.environ["GRASP_BASE_URL"],
        )
        self.container = None

    async def _ensure_container(self):
        """Ensure container is created."""
        if self.container is None:
            self.container = await self.grasp.create()

    async def _cleanup(self):
        """Cleanup container."""
        if self.container:
            try:
                await self.container.shutdown()
            except Exception:
                pass

    async def test_valid_ws_endpoint(self):
        """Test that wsEndpoint is valid."""
        await self._ensure_container()
        try:
            assert self.container.browser.ws_endpoint is not None
            assert self.container.browser.ws_endpoint.startswith(("ws://", "wss://"))
        finally:
            await self._cleanup()

    async def test_valid_live_url(self):
        """Test that liveURL is valid."""
        await self._ensure_container()
        try:
            assert self.container.browser.live_url is not None
            assert self.container.browser.live_url.startswith(("http://", "https://"))
        finally:
            await self._cleanup()

    @pytest.mark.skipif(not PLAYWRIGHT_AVAILABLE, reason="Playwright not installed")
    async def test_connect_via_playwright(self):
        """Test connecting to browser via Playwright."""
        await self._ensure_container()
        try:
            async with async_playwright() as p:
                browser = await p.chromium.connect_over_cdp(
                    endpoint_url=self.container.browser.ws_endpoint
                )

                assert browser is not None
                assert browser.is_connected()

                await browser.close()
        finally:
            await self._cleanup()

    @pytest.mark.skipif(not PLAYWRIGHT_AVAILABLE, reason="Playwright not installed")
    async def test_navigate_and_scrape_content(self):
        """Test navigating to a page and scraping content."""
        await self._ensure_container()
        try:
            async with async_playwright() as p:
                browser = await p.chromium.connect_over_cdp(
                    endpoint_url=self.container.browser.ws_endpoint
                )

                context = await browser.new_context()
                page = await context.new_page()

                await page.goto("https://getgrasp.ai")

                title = await page.title()
                url = page.url

                assert title is not None
                assert isinstance(title, str)
                assert url == "https://getgrasp.ai/"

                await context.close()
                await browser.close()
        finally:
            await self._cleanup()

    async def test_serialize_browser_session(self):
        """Test browser session serialization."""
        await self._ensure_container()
        try:
            browser_serialized = self.container.browser.to_dict()

            assert browser_serialized is not None
            assert browser_serialized["ws_endpoint"] == self.container.browser.ws_endpoint
            assert browser_serialized["live_url"] == self.container.browser.live_url
        finally:
            await self._cleanup()
