"""`scripts/page-probe.py` hands a real browser the right cookie and the right viewport,
and says so in JSON rather than crashing, when it cannot draw the page at all.

What it cost: the first signed-in run of the cross-device pass died on every page with
`Network.setCookie: Sanitizing cookie failed`. The session cookie is named
`__Host-dfp_session`, and that prefix is a rule the browser enforces (no `domain`, path `/`,
`secure`), so a cookie copied out of the login with a `domain` attached is refused outright.
Nine pages at two widths were measured signed out and the signed-in page was simply missing
from the pass until the prefix decided the attributes here.

The measurements themselves run inside Chrome and are not unit-testable without one; they
are proven by the recorded pass in `.logs/verification/`. What is pinned here is everything
a later session can break by editing Python: the cookie rules, the phone decision (a phone
is not a narrow desktop; `mobile` changes which CSS applies), and the promise that a probe
which cannot start a browser prints a JSON object and exits 2 instead of raising, because a
nine-page loop reads exit codes and would otherwise record a missing page as a clean one.
"""

from __future__ import annotations

import importlib.util
import json
import pathlib
import sys

import pytest

SCRIPT = pathlib.Path(__file__).resolve().parents[1] / "scripts" / "page-probe.py"


def load():
    spec = importlib.util.spec_from_file_location("page_probe", SCRIPT)
    module = importlib.util.module_from_spec(spec)
    sys.modules[spec.name] = module
    spec.loader.exec_module(module)
    return module


@pytest.fixture
def probe():
    return load()


def cookie_file(tmp_path: pathlib.Path, text: str) -> pathlib.Path:
    path = tmp_path / "cookie.txt"
    path.write_text(text)
    return path


def test_host_prefixed_cookie_carries_no_domain(probe, tmp_path):
    """The real failure: `__Host-` forbids a domain, and Chrome refuses the whole cookie."""
    path = cookie_file(tmp_path, "__Host-dfp_session=abc123")
    (cookie,) = probe.read_cookies(path, "http://127.0.0.1:8099/collectors")
    assert "domain" not in cookie
    assert cookie["path"] == "/"
    assert cookie["secure"] is True          # 127.0.0.1 counts as a secure origin
    assert cookie["name"] == "__Host-dfp_session"
    assert cookie["value"] == "abc123"


def test_an_ordinary_cookie_is_aimed_at_the_host(probe, tmp_path):
    path = cookie_file(tmp_path, "dfp_session=abc123; other=2")
    session, other = probe.read_cookies(path, "http://127.0.0.1:8099/")
    assert session["domain"] == "127.0.0.1"
    assert session["secure"] is False
    assert other["name"] == "other"


def test_a_secure_prefix_over_https_stays_secure(probe, tmp_path):
    path = cookie_file(tmp_path, "__Secure-thing=1")
    (cookie,) = probe.read_cookies(path, "https://example.test/")
    assert cookie["secure"] is True
    assert cookie["domain"] == "example.test"     # only __Host- forbids one


def test_an_empty_line_is_not_a_cookie(probe, tmp_path):
    assert probe.read_cookies(cookie_file(tmp_path, " ; ;"), "http://127.0.0.1:8099/") == []


@pytest.mark.parametrize("width,phone,height", [(390, True, 844), (1440, False, 900),
                                                (699, True, 844), (700, False, 900)])
def test_the_phone_decision_follows_the_width(probe, width, phone, height):
    assert (width < probe.PHONE_MAX_WIDTH) is phone
    assert probe.DEFAULT_HEIGHTS[phone] == height


def test_no_browser_is_json_and_exit_two(probe, capsys, monkeypatch):
    """A page that could not be drawn is a fact about us, not a clean page: the loop that
    runs nine pages reads the exit code, and an exception would read as a crash, not a gap."""
    monkeypatch.setattr(probe, "CHROME", None)
    code = probe.main(["http://127.0.0.1:1/"])
    assert code == 2
    printed = json.loads(capsys.readouterr().out)
    assert printed["url"] == "http://127.0.0.1:1/"
    assert "no google-chrome" in printed["error"]


def test_the_profile_is_removed_even_when_chrome_never_starts(probe, monkeypatch):
    monkeypatch.setattr(probe, "CHROME", None)
    chrome = probe.Chrome()
    profile = chrome.profile
    assert profile.is_dir()
    with pytest.raises(probe.ProbeError):
        chrome.start()
    chrome.stop()
    assert not profile.exists()


def test_the_overflow_reader_separates_a_shelf_from_a_break(probe):
    """A sideways shelf is a design (the airport page's featured row, every `.scroll-x`
    table); an element with no scrolling ancestor is the finding. The pass reported four
    false breaks on one airport page before the script looked for the scroller."""
    assert "scrollerFor" in probe.OVERFLOW_JS
    assert "'scrolls'" in probe.OVERFLOW_JS
    assert "breaks:" in probe.OVERFLOW_JS
