"""
Smoke tests for browser-hybrid.

Quick validation that core functionality works.
These require Chrome running with --remote-debugging-port=9222.

Run: pytest tests/test_smoke.py -v
"""

from __future__ import annotations

import os
import tempfile

import pytest

from browser_hybrid import Browser
from browser_hybrid.errors import ConnectionError

# Skip all tests in this module if Chrome is not running
# Uses real _check_connection, not mocked
pytestmark = pytest.mark.real_connection_check


@pytest.fixture
def browser():
    """Browser instance for smoke tests."""
    b = None
    try:
        b = Browser()
        yield b
    except ConnectionError:
        pytest.skip("Chrome not running with --remote-debugging-port=9222")
    finally:
        if b:
            try:
                b.close()
            except Exception:
                pass


class TestConnectionSmoke:
    """Smoke tests for basic connectivity."""

    def test_connect(self, browser):
        """Can connect to Chrome."""
        assert browser.is_connected()

    def test_get_version(self, browser):
        """Can get Chrome version."""
        info = browser.get_version()
        assert info.browser is not None
        assert "Chrome" in info.browser

    def test_list_tabs(self, browser):
        """Can list tabs."""
        tabs = browser.list_tabs()
        assert isinstance(tabs, list)


class TestTabSmoke:
    """Smoke tests for tab management."""

    def test_new_tab(self, browser):
        """Can create a new tab."""
        tab = browser.new_tab("about:blank")
        assert tab.id is not None
        assert tab.url == "about:blank"
        browser.close_tab(tab.id)

    def test_close_tab(self, browser):
        """Can close a tab."""
        import time

        # Create a new tab
        new_tab = browser.new_tab("about:blank")

        # Verify tab was created
        all_tabs = browser.list_tabs()
        new_tab_ids = [t.id for t in all_tabs]
        assert new_tab.id in new_tab_ids, "Tab should be in list after creation"

        # Close it
        browser.close_tab(new_tab.id)

        # Give Chrome a moment to process the close
        time.sleep(0.1)

        # Verify it's gone
        remaining_tabs = browser.list_tabs()
        remaining_ids = [t.id for t in remaining_tabs]
        assert new_tab.id not in remaining_ids, "Tab should not be in list after close"

    def test_goto(self, browser):
        """Can navigate to a URL."""
        tab = browser.goto("https://example.com", timeout=1.0)
        assert "example.com" in tab.url
        browser.close_tab(tab.id)


class TestAccessibilitySmoke:
    """Smoke tests for accessibility tree."""

    def test_get_accessibility_tree(self, browser):
        """Can get accessibility tree."""
        tab = browser.goto("https://example.com", timeout=1.0)
        tree = browser.accessibility_tree()

        assert tree is not None
        assert tree.role is not None

        # Should be able to convert to tree string
        tree_str = tree.to_tree_str()
        assert len(tree_str) > 0

        browser.close_tab(tab.id)

    def test_snapshot(self, browser):
        """Can get snapshot string."""
        tab = browser.goto("https://example.com", timeout=1.0)
        snapshot = browser.snapshot()

        assert len(snapshot) > 0
        assert "WebArea" in snapshot or "document" in snapshot

        browser.close_tab(tab.id)


class TestInteractSmoke:
    """Smoke tests for interactions."""

    def test_evaluate_javascript(self, browser):
        """Can execute JavaScript."""
        tab = browser.goto("https://example.com", timeout=1.0)
        result = browser.evaluate("document.title")
        assert result == "Example Domain"
        browser.close_tab(tab.id)

    def test_get_html(self, browser):
        """Can get page HTML."""
        tab = browser.goto("https://example.com", timeout=1.0)
        html = browser.get_html()
        assert "<!doctype" in html.lower() or "<html" in html.lower()
        browser.close_tab(tab.id)

    def test_screenshot(self, browser):
        """Can take screenshot."""
        tab = browser.goto("https://example.com", timeout=1.0)

        with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as f:
            path = f.name

        try:
            result_path = browser.screenshot(path)
            assert os.path.exists(result_path)
            assert os.path.getsize(result_path) > 0
        finally:
            if os.path.exists(path):
                os.unlink(path)

        browser.close_tab(tab.id)


class TestConnectionPoolSmoke:
    """Smoke tests for connection pool."""

    def test_connection_reuse(self, browser):
        """Connection is reused across operations."""
        tab = browser.goto("https://example.com", timeout=1.0)

        # Multiple operations should reuse connection
        browser.accessibility_tree()
        browser.evaluate("1 + 1")
        browser.get_html()

        # Check pool has active connection
        pool = browser._pool
        if pool:
            # At least one connection should be active
            assert pool.active_count >= 1

        browser.close_tab(tab.id)

    def test_multiple_tabs(self, browser):
        """Can handle multiple tabs with separate connections."""
        tab1 = browser.new_tab("https://example.com")
        tab2 = browser.new_tab("https://example.org")

        # Both should work
        tree1 = browser.accessibility_tree(tab1)
        tree2 = browser.accessibility_tree(tab2)

        assert tree1 is not None
        assert tree2 is not None

        browser.close_tab(tab1.id)
        browser.close_tab(tab2.id)


class TestErrorHandlingSmoke:
    """Smoke tests for error handling."""

    def test_connection_error_context(self):
        """ConnectionError includes context."""
        import browser_hybrid.errors as errors

        err = errors.ConnectionError(
            "Chrome not reachable",
            host="localhost",
            port=9222,
        )
        assert "localhost" in str(err)
        assert "9222" in str(err)

    def test_timeout_error_context(self):
        """TimeoutError includes context."""
        import browser_hybrid.errors as errors

        err = errors.TimeoutError(
            "Navigation timed out",
            timeout=30.0,
            operation="navigate",
        )
        assert "30.0" in str(err)
        assert "navigate" in str(err)
