"""전체 Chrome suite와 실제 자식 Chrome/renderer의 sandbox 인자를 새 증거로 보존한다."""
import json
import os
from pathlib import Path
import subprocess
import time

EVIDENCE = Path(__file__).resolve().parent
ROOT = EVIDENCE.parents[2]
environment = dict(os.environ)
environment.pop("PLAYWRIGHT_NO_SANDBOX", None)
environment["CHROME_PATH"] = "/usr/bin/google-chrome"
environment["PLAYWRIGHT_JSON_OUTPUT_NAME"] = str(EVIDENCE / "browser-results.json")
command = ["npx", "playwright", "test", "--reporter=line,json", f"--output={EVIDENCE / 'browser-artifacts'}"]
observed = {}
with (EVIDENCE / "09-browser.log").open("x") as log:
    process = subprocess.Popen(command, cwd=ROOT, env=environment, stdout=log, stderr=subprocess.STDOUT)
    while process.poll() is None:
        parents = {}
        for path in Path("/proc").glob("[0-9]*"):
            try:
                status = dict(line.split(":", 1) for line in (path / "status").read_text().splitlines())
                parents[int(path.name)] = (int(status["PPid"]), path, status)
            except (OSError, ValueError, KeyError):
                continue
        children = {process.pid}
        while True:
            expanded = children | {pid for pid, (ppid, _, _) in parents.items() if ppid in children}
            if children == expanded:
                break
            children = expanded
        for pid in children:
            if pid in observed or pid not in parents:
                continue
            _, path, status = parents[pid]
            try:
                if (path / "exe").resolve().name != "chrome":
                    continue
                args = (path / "cmdline").read_bytes().decode().strip("\0").split("\0")
                observed[pid] = {"pid": pid, "argv": args,
                                 "seccomp": status.get("Seccomp", "").strip(),
                                 "noNewPrivs": status.get("NoNewPrivs", "").strip()}
            except OSError:
                continue
        time.sleep(0.5)
    code = process.wait()
has_browser = any(not any(arg.startswith("--type=") for arg in row["argv"]) for row in observed.values())
has_renderer = any("--type=renderer" in row["argv"] for row in observed.values())
sandbox = bool(observed) and all("--no-sandbox" not in row["argv"] for row in observed.values())
report = {"command": command, "exitCode": code, "chromiumSandbox": True,
          "chromeVersion": subprocess.check_output([environment["CHROME_PATH"], "--version"], text=True).strip(),
          "browserObserved": has_browser, "rendererObserved": has_renderer,
          "noSandboxFlagAbsent": sandbox, "processes": list(observed.values())}
(EVIDENCE / "chrome-sandbox.json").write_text(json.dumps(report, indent=2) + "\n")
print(json.dumps({key: value for key, value in report.items() if key != "processes"}, indent=2))
if code or not (has_browser and has_renderer and sandbox):
    raise SystemExit(code or 1)
