"""
Tests for Feature 2: Browser Automation (Playwright).
  - URL blocklist enforced before any network call
  - search action returns results (mocked)
  - Live navigate test (requires network — opt-in marker)
"""

import pytest
from unittest.mock import AsyncMock, MagicMock, patch


# ── URL blocklist (no Playwright needed) ──────────────────────────────────────

class TestUrlBlocklist:
    """Dangerous URLs are rejected before any browser/network activity."""

    @pytest.fixture
    def browser_skill(self, auto_approve_engine):
        from duckclaw.skills.web_browser import WebBrowserSkill
        return WebBrowserSkill(auto_approve_engine)

    async def test_localhost_url_blocked(self, browser_skill):
        result = await browser_skill.execute("navigate", {"url": "http://localhost/admin"})
        assert result.success is False
        assert "blocked" in result.error.lower()

    async def test_localhost_with_port_blocked(self, browser_skill):
        result = await browser_skill.execute("navigate", {"url": "http://localhost:8741"})
        assert result.success is False
        assert "blocked" in result.error.lower()

    async def test_127_0_0_1_blocked(self, browser_skill):
        result = await browser_skill.execute("navigate", {"url": "http://127.0.0.1/secret"})
        assert result.success is False
        assert "blocked" in result.error.lower()

    async def test_file_protocol_blocked(self, browser_skill):
        result = await browser_skill.execute("navigate", {"url": "file:///etc/passwd"})
        assert result.success is False
        assert "blocked" in result.error.lower()

    async def test_private_ip_192_168_blocked(self, browser_skill):
        result = await browser_skill.execute("navigate", {"url": "http://192.168.1.1/"})
        assert result.success is False
        assert "blocked" in result.error.lower()

    async def test_onion_domain_blocked(self, browser_skill):
        result = await browser_skill.execute("navigate", {"url": "http://somehiddensite.onion"})
        assert result.success is False
        assert "blocked" in result.error.lower()


# ── Search action (mocked DDG) ─────────────────────────────────────────────────

class TestWebSearch:
    """Search uses duckduckgo_search; mocked to avoid network dependency."""

    async def test_search_returns_result_list(self, auto_approve_engine):
        from duckclaw.skills.web_browser import WebBrowserSkill

        fake_results = [
            {"title": "Python.org", "href": "https://python.org", "body": "Python programming language."},
            {"title": "PyPI", "href": "https://pypi.org", "body": "Python Package Index."},
        ]

        skill = WebBrowserSkill(auto_approve_engine)

        with patch("duckduckgo_search.DDGS") as mock_ddgs:
            mock_ddgs.return_value.__enter__ = MagicMock(return_value=mock_ddgs.return_value)
            mock_ddgs.return_value.__exit__ = MagicMock(return_value=False)
            mock_ddgs.return_value.text = MagicMock(return_value=fake_results)

            result = await skill.execute("search", {"query": "Python programming"})

        assert result.success is True
        assert isinstance(result.data, list)
        assert len(result.data) >= 1

    async def test_search_missing_query_fails(self, auto_approve_engine):
        from duckclaw.skills.web_browser import WebBrowserSkill
        skill = WebBrowserSkill(auto_approve_engine)
        result = await skill.execute("search", {})
        assert result.success is False
        assert "query" in result.error.lower()

    async def test_unknown_action_returns_error(self, auto_approve_engine):
        from duckclaw.skills.web_browser import WebBrowserSkill
        skill = WebBrowserSkill(auto_approve_engine)
        result = await skill.execute("invalid_action", {})
        assert result.success is False


# ── Live integration test (requires real network + Playwright) ─────────────────

@pytest.mark.network
class TestLiveNavigation:
    """Real browser navigation — skipped unless --run-network passed."""

    async def test_navigate_to_public_url_returns_title(self, auto_approve_engine):
        """Navigate to a public URL and return page title + content."""
        from duckclaw.skills.web_browser import WebBrowserSkill
        skill = WebBrowserSkill(auto_approve_engine)

        try:
            result = await skill.execute("navigate", {"url": "https://example.com"})
            assert result.success is True
            assert "title" in result.data
            assert len(result.data["title"]) > 0
        finally:
            await skill._close_browser()
