from __future__ import annotations

import json
import re
import subprocess
import urllib.error
import urllib.request
from pathlib import Path

import pytest

from nomo_e2e.discovery import WebViewDiscovery


def _is_webdriver_ready(endpoint: str) -> bool:
    try:
        with urllib.request.urlopen(f"{endpoint.rstrip('/')}/status", timeout=2):
            return True
    except urllib.error.URLError:
        return False


def _extract_summary(output: str) -> dict[str, int]:
    import re

    pattern = r"\{[^}]*\"click_steps\"[^}]*\}"
    match = re.search(pattern, output)
    if match:
        try:
            payload = json.loads(match.group())
            click_steps = int(payload.get("click_steps", 0))
            failed_steps = int(payload.get("failed_steps", 0))
            return {"click_steps": click_steps, "failed_steps": failed_steps}
        except json.JSONDecodeError:
            pass
    return {"click_steps": 0, "failed_steps": 0}


def test_webdriver_parity_cli_command() -> None:
    endpoint = "http://127.0.0.1:4445"
    if not _is_webdriver_ready(endpoint):
        pytest.skip("WebDriver endpoint is not ready on 127.0.0.1:4445")
    discovery = WebViewDiscovery()
    matched = discovery.find_by_name("GoldenIdea")
    if not matched:
        pytest.skip("GoldenIdea process not found")
    command = [
        "uv",
        "run",
        "python",
        "main.py",
        "--driver",
        "webdriver",
        "--endpoint",
        endpoint,
        "--expect-selector",
        "body",
        "--min-count",
        "1",
        "--max-click-targets",
        "8",
    ]
    result = subprocess.run(
        command,
        cwd=str(Path(__file__).resolve().parents[1]),
        capture_output=True,
        text=True,
        check=False,
    )
    output = (result.stdout or "") + "\n" + (result.stderr or "")
    assert "驱动类型: webdriver" in output
    assert "会话已创建" in output
    assert "可点击目标列表:" in output
    assert "累计控制台错误:" in output
    summary = _extract_summary(output)
    assert summary["click_steps"] > 0
    assert result.returncode in {0, 1}
    if result.returncode == 1:
        error_msg = output.encode().decode("unicode_escape")
        assert (
            re.search("click_steps.*failed_steps|渲染断言失败|前端报错命中禁用模式", error_msg)
            or "FAIL" in error_msg
        )
