"""One no-proxy Patchright attempt on the existing Amazon laptop-search URL."""
import json
import os
import platform
import sys
import threading
import time
from datetime import datetime, timezone
from importlib.metadata import version
from pathlib import Path

import psutil
from bs4 import BeautifulSoup

HERE = Path(__file__).resolve().parent
URL = "https://www.amazon.com/s?k=laptop"
BLOCK_MARKERS = (
    "robot check", "enter the characters", "verify you are human",
    "just a moment", "access denied", "checking your browser",
)


def main():
    for key in ("HTTP_PROXY", "HTTPS_PROXY", "ALL_PROXY", "http_proxy", "https_proxy", "all_proxy"):
        os.environ.pop(key, None)
    row = {
        "tool": "Patchright", "tool_version": version("patchright"),
        "python_version": platform.python_version(), "runtime": platform.platform(),
        "target": "amazon_search_laptop", "url": URL,
        "started_at": datetime.now(timezone.utc).isoformat(),
        "command": [sys.executable, *sys.argv],
        "config": {"browser": "chromium", "headless": True, "proxy": None,
                   "wait_until": "domcontentloaded", "navigation_timeout_ms": 30000,
                   "content_wait_ms": 8000, "settle_ms": 500},
        "network": "this host, direct outbound; common proxy environment variables removed",
        "resource_metric_caveat": "Peak sampled sum of Python and descendant browser PSS/RSS at 0.2-second intervals; may miss brief peaks and is not comparable to the earlier Zenbook browser run.",
    }
    stop = threading.Event()
    samples = []

    def sample_tree():
        root = psutil.Process(os.getpid())
        while not stop.is_set():
            pss = rss = count = 0
            try:
                members = [root, *root.children(recursive=True)]
            except psutil.NoSuchProcess:
                break
            for proc in members:
                try:
                    memory = proc.memory_full_info()
                    pss += getattr(memory, "pss", memory.rss)
                    rss += memory.rss
                    count += 1
                except (psutil.NoSuchProcess, psutil.AccessDenied, psutil.ZombieProcess):
                    pass
            samples.append((pss, rss, count))
            stop.wait(0.2)

    monitor = threading.Thread(target=sample_tree, daemon=True)
    monitor.start()
    start = time.perf_counter()
    try:
        from patchright.sync_api import sync_playwright

        with sync_playwright() as playwright:
            row["browser_executable"] = playwright.chromium.executable_path
            browser = playwright.chromium.launch(headless=True)
            try:
                row["browser_version"] = browser.version
                page = browser.new_page()
                try:
                    response = page.goto(URL, wait_until="domcontentloaded", timeout=30000)
                    row["http_status"] = response.status if response else None
                    row["navigation_outcome"] = "returned"
                    if row["http_status"] == 200:
                        try:
                            page.wait_for_function("() => document.body && document.body.innerText.length >= 500", timeout=8000)
                        except Exception:
                            pass
                    page.wait_for_timeout(500)
                    row["final_url"] = page.url
                    row["title"] = page.title()
                    html = page.content()
                    text = page.locator("body").inner_text(timeout=5000)
                    (HERE / "rendered-html.txt").write_text(html, encoding="utf-8")
                    (HERE / "visible-text.txt").write_text(text, encoding="utf-8")
                    row.update(rendered_html="rendered-html.txt", visible_text="visible-text.txt",
                               html_bytes=len(html.encode("utf-8")), visible_text_chars=len(text))
                    page.screenshot(path=str(HERE / "screenshot.png"), full_page=False, timeout=10000)
                    row["screenshot"] = "screenshot.png"
                    soup = BeautifulSoup(html, "html.parser")
                    cards = [card for card in soup.select('[data-component-type="s-search-result"]')
                             if card.get("data-asin") and card.select_one("h2")]
                    low = (row["title"] + "\n" + text[:2000]).lower()
                    block_markers = [marker for marker in BLOCK_MARKERS if marker in low]
                    row.update(product_result_count=len(cards), required_term_found="laptop" in text.lower(),
                               block_markers=block_markers, empty_or_short_200=row["http_status"] == 200 and len(text) < 500,
                               usable_content=row["http_status"] == 200 and len(cards) > 0 and "laptop" in text.lower()
                               and len(text) >= 500 and not block_markers)
                finally:
                    page.close()
            finally:
                browser.close()
    except Exception as exc:
        row.update(navigation_outcome=row.get("navigation_outcome", "error"),
                   error=f"{type(exc).__name__}: {str(exc)[:500]}", usable_content=False)
    finally:
        row["wall_seconds"] = round(time.perf_counter() - start, 3)
        row["finished_at"] = datetime.now(timezone.utc).isoformat()
        stop.set()
        monitor.join(timeout=1)
        row["sampled_peak_process_tree_pss_mb"] = round(max((s[0] for s in samples), default=0) / 1048576, 1)
        row["sampled_peak_process_tree_rss_sum_mb"] = round(max((s[1] for s in samples), default=0) / 1048576, 1)
        row["sampled_max_process_count"] = max((s[2] for s in samples), default=0)
        row["resource_sample_interval_seconds"] = 0.2
        (HERE / "result.json").write_text(json.dumps(row, indent=2) + "\n", encoding="utf-8")
        print(json.dumps(row, indent=2))


if __name__ == "__main__":
    main()
