from __future__ import annotations

import argparse
import hashlib
import json
import os
import pathlib
import sys
import threading
import unittest
import time


ROOT = pathlib.Path(__file__).resolve().parent
os.environ.setdefault("PYTHONPYCACHEPREFIX", str(ROOT / "artifacts" / "runtime_pycache" / f"{os.getpid()}-{time.time_ns()}"))
sys.path.insert(0, str(ROOT))
sys.path.insert(0, str(ROOT / "src"))


RISK_GROUPS = {
    "isolated_001": ["tests.test_r4_rg.R4RegressionTests.test_r4_rg_05"],
    "isolated_002": ["tests.test_r5_rg.R5RegressionTests.test_r5_rg_01"],
    "isolated_003": ["tests.test_r5_rg.R5RegressionTests.test_r5_rg_02"],
    "isolated_004": ["tests.test_r5_rg.R5RegressionTests.test_r5_rg_03"],
    "isolated_005": ["tests.test_r5_rg.R5RegressionTests.test_r5_rg_04"],
    "isolated_006": ["tests.test_r5_rg.R5RegressionTests.test_r5_rg_05"],
    "isolated_007": ["tests.test_r5_rg.R5RegressionTests.test_r5_rg_06"],
    "isolated_008": ["tests.test_r5_rg.R5RegressionTests.test_r5_rg_07"],
    "isolated_009": ["tests.test_r6_rg.R6RegressionTests.test_r6_rg_01"],
    "isolated_010": ["tests.test_r6_rg.R6RegressionTests.test_r6_rg_05"],
    "isolated_011": ["tests.test_r6_rg.R6RegressionTests.test_r6_rg_06"],
    "isolated_012": ["tests.test_r6_rg.R6RegressionTests.test_r6_rg_07"],
    "isolated_013": ["tests.test_r6_rg.R6RegressionTests.test_r6_rg_08"],
    "isolated_014": ["tests.test_r6_rg.R6RegressionTests.test_r6_rg_09"],
    "isolated_015": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_01"],
    "isolated_016": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_02"],
    "isolated_017": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_03"],
    "isolated_018": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_04"],
    "isolated_019": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_05"],
    "isolated_020": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_06"],
    "isolated_021": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_07"],
    "isolated_022": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_08"],
    "isolated_023": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_09"],
    "isolated_024": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_10"],
    "isolated_025": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_11"],
    "isolated_026": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_12"],
    "isolated_027": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_13"],
    "isolated_028": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_14"],
    "isolated_029": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_15"],
    "isolated_030": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_16"],
    "isolated_031": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_17"],
    "isolated_032": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_18"],
    "isolated_033": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_19"],
    "isolated_034": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_20"],
    "isolated_035": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_21"],
    "isolated_036": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_22"],
    "isolated_037": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_23"],
    "isolated_038": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_24"],
    "isolated_039": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_25"],
    "isolated_040": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_26"],
    "isolated_041": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_27"],
    "isolated_042": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_28"],
    "isolated_043": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_29"],
    "isolated_044": ["tests.test_r7_rg.R7RegressionTests.test_r7_rg_30"],
    "isolated_045": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_01"],
    "isolated_046": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_02"],
    "isolated_047": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_03"],
    "isolated_048": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_04"],
    "isolated_049": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_05"],
    "isolated_050": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_06"],
    "isolated_051": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_07"],
    "isolated_052": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_08"],
    "isolated_053": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_09"],
    "isolated_054": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_10"],
    "isolated_055": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_11"],
    "isolated_056": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_12"],
    "isolated_057": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_13"],
    "isolated_058": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_14"],
    "isolated_059": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_15"],
    "isolated_060": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_16"],
    "isolated_061": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_17"],
    "isolated_062": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_18"],
    "isolated_063": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_19"],
    "isolated_064": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_20"],
    "isolated_065": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_21"],
    "isolated_066": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_22"],
    "isolated_067": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_23"],
    "isolated_068": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_24"],
    "isolated_069": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_25"],
    "isolated_070": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_26"],
    "isolated_071": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_27"],
    "isolated_072": ["tests.test_r8_rg.R8RegressionTests.test_r8_rg_28"],
}


def _flatten(suite: unittest.TestSuite):
    for item in suite:
        if isinstance(item, unittest.TestSuite):
            yield from _flatten(item)
        else:
            yield item


class HeartbeatResult(unittest.TextTestResult):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.last_started: str | None = None
        self.last_completed: str | None = None
        self.failed_ids: set[str] = set()
        self._heartbeat_stop: threading.Event | None = None
        self._heartbeat_thread: threading.Thread | None = None

    def _emit(self, event: str, test_id: str, **fields) -> None:
        print("TEST_HEARTBEAT " + json.dumps({"event": event, "test_id": test_id, "epoch": time.time(), "pid": os.getpid(), **fields}, sort_keys=True), flush=True)

    def startTest(self, test):
        self.last_started = test.id()
        self._emit("START", self.last_started)
        self._heartbeat_stop = threading.Event()
        current_id = self.last_started
        def pulse() -> None:
            assert self._heartbeat_stop is not None
            while not self._heartbeat_stop.wait(0.5):
                self._emit("PULSE", current_id)
        self._heartbeat_thread = threading.Thread(target=pulse, name=f"test-heartbeat-{os.getpid()}", daemon=True)
        self._heartbeat_thread.start()
        super().startTest(test)

    def addFailure(self, test, err):
        self.failed_ids.add(test.id()); super().addFailure(test, err)

    def addError(self, test, err):
        self.failed_ids.add(test.id()); super().addError(test, err)

    def stopTest(self, test):
        self.last_completed = test.id()
        if self._heartbeat_stop is not None:
            self._heartbeat_stop.set()
        if self._heartbeat_thread is not None:
            self._heartbeat_thread.join(timeout=2)
        self._emit("END", self.last_completed, status="FAIL" if self.last_completed in self.failed_ids else "PASS")
        super().stopTest(test)


def _selected_worker_suite() -> unittest.TestSuite:
    included_names = json.loads(os.environ.get("WRLAB_TEST_FILTER", "[]"))
    if not isinstance(included_names, list) or not all(isinstance(name, str) and name for name in included_names):
        raise ValueError("WRLAB_TEST_FILTER must be a JSON list of non-empty test IDs")
    if len(included_names) != len(set(included_names)):
        raise ValueError("WRLAB_TEST_FILTER contains duplicate test IDs")
    excluded = set(json.loads(os.environ.get("WRLAB_TEST_EXCLUDE", "[]")))
    if included_names:
        requested = unittest.defaultTestLoader.loadTestsFromNames(included_names)
        selected = [test for test in _flatten(requested) if test.id() not in excluded]
        return unittest.TestSuite(selected)
    discovered = unittest.defaultTestLoader.discover(str(ROOT / "tests"), top_level_dir=str(ROOT))
    selected = [test for test in _flatten(discovered) if test.id() not in excluded]
    return unittest.TestSuite(selected)


def run_tests_worker() -> bool:
    suite = _selected_worker_suite()
    runner = unittest.TextTestRunner(stream=sys.stdout, verbosity=2, resultclass=HeartbeatResult)
    result = runner.run(suite)
    report = {
        "group": os.environ.get("WRLAB_TEST_GROUP", "unfiltered"),
        "tests_run": result.testsRun,
        "failure_count": len(result.failures),
        "error_count": len(result.errors),
        "failed_test_ids": sorted(result.failed_ids),
        "last_started": result.last_started,
        "last_completed": result.last_completed,
        "passed": result.wasSuccessful(),
    }
    print("TEST_WORKER_REPORT " + json.dumps(report, sort_keys=True), flush=True)
    return result.wasSuccessful()


def run_tests(order_name: str = "default", random_seed: int | None = None, load_profile: str = "normal") -> bool:
    from reliability_core.process_control import cleanup_reserve_seconds, run_supervised_process, total_timeout_for_operation
    from reliability_core.suite_isolation import (
        SAFE_SHARED_WORKER,
        calibrated_worker_process_floor,
        calibrate_python_startup,
        calibrate_worker_import_discovery,
        environment_digest,
        load_policy_manifest,
        ordered_test_ids,
        policy_index,
        partition_timeout_bounded_tests,
        sha256_file,
        suite_total_budget,
        timeout_profile_budget,
        validate_policy_manifest,
    )
    from reliability_core.policy_audit_r10r2 import audit_test_sources, validate_independent_policy
    from reliability_core.stage_control_r10r3r2 import execution_cost_p95, group_admission, load_deadline_calibration

    suite_started = time.monotonic()
    manifest_path = ROOT / "test_execution_manifest.json"
    all_ids = sorted(test.id() for test in _flatten(unittest.defaultTestLoader.discover(str(ROOT / "tests"), top_level_dir=str(ROOT))))
    try:
        manifest = load_policy_manifest(manifest_path)
        manifest_validation = validate_policy_manifest(manifest, all_ids)
    except Exception as error:
        manifest_validation = {"passed": False, "error": f"{type(error).__name__}:{error}", "discovered_count": len(all_ids)}
        print("POLICY_MANIFEST_REPORT " + json.dumps(manifest_validation, sort_keys=True), flush=True)
        return False
    print("POLICY_MANIFEST_REPORT " + json.dumps(manifest_validation, sort_keys=True), flush=True)
    if not manifest_validation["passed"]:
        return False
    ast_audit = audit_test_sources(ROOT, all_ids)
    runtime_sensitive = [
        str(row["test_id"]) for row in manifest.get("tests", [])
        if isinstance(row, dict) and row.get("policy") != "SAFE_SHARED_WORKER"
    ]
    independent_policy = validate_independent_policy(all_ids, manifest, ast_audit, runtime_sensitive)
    print("POLICY_AUDIT_REPORT " + json.dumps(independent_policy, sort_keys=True), flush=True)
    if not independent_policy["passed"]:
        return False
    policies = policy_index(manifest)
    calibration = calibrate_python_startup(ROOT)
    worker_calibration = calibrate_worker_import_discovery(ROOT)
    worker_process_floor = calibrated_worker_process_floor(worker_calibration)
    deadline_calibration = load_deadline_calibration()
    if not calibration.passed:
        print("STARTUP_CALIBRATION_REPORT " + json.dumps(calibration.to_dict(), sort_keys=True), flush=True)
        return False
    ordered_ids = ordered_test_ids(all_ids, policies, order_name, random_seed)
    isolated_count = sum(policies[test_id]["policy"] != SAFE_SHARED_WORKER for test_id in all_ids)
    timeout_profiles = [str(policies[test_id]["timeout_profile"]) for test_id in all_ids]
    profile_counts = {profile: timeout_profiles.count(profile) for profile in sorted(set(timeout_profiles))}
    derived_suite_timeout = suite_total_budget(calibration, isolated_count, len(all_ids) - isolated_count, timeout_profiles=timeout_profiles)
    configured_timeout = os.environ.get("WRLAB_SUITE_TOTAL_SECONDS")
    suite_timeout = min(900.0, float(configured_timeout)) if configured_timeout else derived_suite_timeout
    suite_deadline = suite_started + suite_timeout
    print("STARTUP_CALIBRATION_REPORT " + json.dumps({**calibration.to_dict(), "timeout_profile_counts": profile_counts, "derived_suite_timeout_seconds": derived_suite_timeout, "applied_suite_timeout_seconds": suite_timeout}, sort_keys=True), flush=True)
    print("WORKER_IMPORT_CALIBRATION_REPORT " + json.dumps(worker_calibration.to_dict(), sort_keys=True), flush=True)
    groups: list[tuple[str, list[str], str]] = []
    safe_segment: list[str] = []
    safe_index = 0
    for test_id in ordered_ids:
        policy = str(policies[test_id]["policy"])
        if policy == SAFE_SHARED_WORKER:
            safe_segment.append(test_id)
            continue
        if safe_segment:
            safe_index += 1
            groups.append((f"safe_segment_{safe_index:03d}", safe_segment, SAFE_SHARED_WORKER))
            safe_segment = []
        groups.append((f"isolated_{len(groups)+1:03d}", [test_id], policy))
    if safe_segment:
        safe_index += 1
        groups.append((f"safe_segment_{safe_index:03d}", safe_segment, SAFE_SHARED_WORKER))
    # A sensitive-first order intentionally clusters every isolated test before the
    # shared-safe tail.  Keep that order, but divide an oversized tail so one worker
    # cannot reserve most of the suite deadline and be rejected before it starts.
    # The ceiling is derived from this run's suite and phase calibration, not from a
    # larger timeout constant or a cached prior result.
    worker_window_seconds = suite_timeout / 4.0
    shared_execution_ceiling = max(
        deadline_calibration.execution_p95_seconds,
        worker_window_seconds
        - deadline_calibration.startup_p95_seconds
        - deadline_calibration.drain_p95_seconds
        - cleanup_reserve_seconds(worker_window_seconds),
    )
    bounded_groups: list[tuple[str, list[str], str]] = []
    for group_name, test_ids, policy in groups:
        if policy != SAFE_SHARED_WORKER or len(test_ids) <= 1:
            bounded_groups.append((group_name, test_ids, policy))
            continue
        chunks = partition_timeout_bounded_tests(
            test_ids,
            {test_id: str(policies[test_id]["timeout_profile"]) for test_id in test_ids},
            maximum_execution_cost_seconds=shared_execution_ceiling,
            worker_process_floor_seconds=worker_process_floor,
            shared_safe_observed_p95_seconds=worker_calibration.p95_seconds,
        )
        if len(chunks) == 1:
            bounded_groups.append((group_name, list(chunks[0]), policy))
            continue
        for chunk_index, chunk in enumerate(chunks, start=1):
            bounded_groups.append((f"{group_name}_part_{chunk_index:03d}", list(chunk), policy))
    groups = bounded_groups
    manifest_digest = sha256_file(manifest_path)
    controller_run_id = f"r9-{os.getpid()}-{time.time_ns()}"
    raw_root = ROOT / "artifacts" / "test_workers" / controller_run_id
    raw_root.mkdir(parents=True, exist_ok=False)
    phase_json = json.dumps(calibration.to_dict(), sort_keys=True)
    deadline_json = json.dumps(deadline_calibration.to_dict(), sort_keys=True)
    records: list[dict[str, object]] = []
    completed_ids: list[str] = []
    def forward_stdout(data: bytes) -> None:
        sys.stdout.buffer.write(data); sys.stdout.buffer.flush()
    def forward_stderr(data: bytes) -> None:
        sys.stderr.buffer.write(data); sys.stderr.buffer.flush()
    for group_index, (group_name, test_ids, policy) in enumerate(groups):
        if not test_ids:
            continue
        remaining = suite_deadline - time.monotonic()
        profile_floor = worker_process_floor + timeout_profile_budget(
            (str(policies[test_id]["timeout_profile"]) for test_id in test_ids),
            shared_safe_observed_p95_seconds=worker_calibration.p95_seconds,
        )
        group_execution_cost = execution_cost_p95(deadline_calibration, profile_floor)
        admission = group_admission(remaining, deadline_calibration, group_execution_cost)
        operation_budget = (
            admission["startup_p95_seconds"]
            + admission["execution_cost_p95_seconds"]
            + admission["drain_p95_seconds"]
        )
        per_worker_limit = total_timeout_for_operation(operation_budget)
        admission.update({
            "worker_import_discovery_p95_seconds": worker_calibration.p95_seconds,
            "worker_process_floor_seconds": worker_process_floor,
            "worker_startup_jitter_seconds": worker_process_floor - worker_calibration.p95_seconds,
            "worker_observed_jitter_seconds": (worker_process_floor - worker_calibration.p95_seconds) / 2.0,
            "shared_safe_observed_p95_seconds": worker_calibration.p95_seconds,
            "operation_budget_seconds": operation_budget,
            "shared_execution_ceiling_seconds": shared_execution_ceiling,
            "worker_window_seconds": worker_window_seconds,
            "required_seconds": per_worker_limit,
            "admitted": remaining >= per_worker_limit,
        })
        if not admission["admitted"]:
            records.append({"group": group_name, "policy": policy, "started": False, "reason": "group_admission_budget_insufficient", "test_count": len(test_ids), "admission": admission})
            break
        environment = {**os.environ, "WRLAB_TEST_WORKER": "1", "WRLAB_TEST_GROUP": group_name, "WRLAB_TEST_FILTER": json.dumps(test_ids), "WRLAB_PHASE_BUDGET_JSON": phase_json, "R10_R3_DEADLINE_CALIBRATION_JSON": deadline_json, "WRLAB_ORDER_NAME": order_name, "WRLAB_RANDOM_SEED": "" if random_seed is None else str(random_seed), "WRLAB_LOAD_PROFILE": load_profile, "PYTHONDONTWRITEBYTECODE": "1"}
        print("GROUP_HEARTBEAT " + json.dumps({"event": "START", "group": group_name, "policy": policy, "test_ids": test_ids, "epoch": time.time()}, sort_keys=True), flush=True)
        record = run_supervised_process(
            [sys.executable, str(pathlib.Path(__file__).resolve()), "--test-worker"],
            ROOT,
            environment=environment,
            total_timeout_seconds=min(per_worker_limit, max(time.get_clock_info("monotonic").resolution, remaining - deadline_calibration.reserve_seconds)),
            max_output_bytes=4 * 1024 * 1024,
            stdout_callback=forward_stdout,
            stderr_callback=forward_stderr,
        )
        print("GROUP_HEARTBEAT " + json.dumps({"event": "END", "group": group_name, "policy": policy, "exit_code": record["exit_code"], "epoch": time.time()}, sort_keys=True), flush=True)
        stem = f"{group_index:03d}-{test_ids[0].replace('.', '_') if len(test_ids)==1 else group_name}"
        stdout_path = raw_root / f"{stem}.stdout.txt"
        stderr_path = raw_root / f"{stem}.stderr.txt"
        stdout_path.write_text(record["stdout"], encoding="utf-8")
        stderr_path.write_text(record["stderr"], encoding="utf-8")
        worker_reports = [json.loads(line.split(" ", 1)[1]) for line in record["stdout"].splitlines() if line.startswith("TEST_WORKER_REPORT ")]
        heartbeats = [json.loads(line.split(" ", 1)[1]) for line in record["stdout"].splitlines() if line.startswith("TEST_HEARTBEAT ")]
        worker = worker_reports[-1] if worker_reports else {}
        ended = [row["test_id"] for row in heartbeats if row["event"] == "END"]
        completed_ids.extend(ended)
        records.append({
            "group": group_name,
            "test_id": test_ids[0] if len(test_ids) == 1 else None,
            "test_ids": test_ids,
            "policy": policy,
            "admission": admission,
            "started": True,
            "expected_test_count": len(test_ids),
            "worker_test_count": worker.get("tests_run", 0),
            "worker_pid": record["pid"],
            "started_epoch": record.get("started_epoch"),
            "ended_epoch": record.get("ended_epoch"),
            "exit_code": record["exit_code"],
            "timed_out": record["timed_out"],
            "stdout_file": str(stdout_path.relative_to(ROOT)).replace("\\", "/"),
            "stderr_file": str(stderr_path.relative_to(ROOT)).replace("\\", "/"),
            "stdout_sha256": hashlib.sha256(stdout_path.read_bytes()).hexdigest(),
            "stderr_sha256": hashlib.sha256(stderr_path.read_bytes()).hexdigest(),
            "orphan_process_count": record["orphan_process_count"],
            "zombie_process_count": record["zombie_process_count"],
            "cleanup_passed": record["orphan_process_count"] == 0 and record["zombie_process_count"] == 0 and record["output_drain_threads_stopped"],
            "output_drain_threads_stopped": record["output_drain_threads_stopped"],
            "environment_sha256": environment_digest(environment),
            "policy_manifest_sha256": manifest_digest,
            "order_name": order_name,
            "order_index": group_index,
            "random_seed": random_seed,
            "load_profile": load_profile,
            "last_started": next((row["test_id"] for row in reversed(heartbeats) if row["event"] == "START"), None),
            "last_completed": next((row["test_id"] for row in reversed(heartbeats) if row["event"] == "END"), None),
            "worker_report": worker,
        })
    duplicate_ids = sorted({test_id for test_id in completed_ids if completed_ids.count(test_id) > 1})
    missing_ids = sorted(set(all_ids) - set(completed_ids))
    unexpected_ids = sorted(set(completed_ids) - set(all_ids))
    total_tests = len(completed_ids)
    passed = total_tests == len(all_ids) and not duplicate_ids and not missing_ids and not unexpected_ids and all(row.get("started") and row.get("exit_code") == 0 and row.get("timed_out") is False and row.get("orphan_process_count") == 0 and row.get("zombie_process_count") == 0 and row.get("worker_test_count") == row.get("expected_test_count") and row.get("cleanup_passed") is True for row in records)
    print(f"Ran {total_tests} tests in {time.monotonic() - suite_started:.3f}s")
    print("OK" if passed else "FAILED")
    print("WATCHDOG_REPORT " + json.dumps({"watchdog": "sacrificial_subprocess_per_sensitive_test", "compatibility_watchdog": "sacrificial_subprocess_per_risk_group", "controller_run_id": controller_run_id, "suite_total_timeout_seconds": suite_timeout, "suite_elapsed_ms": round((time.monotonic()-suite_started)*1000, 3), "discovered_test_count": len(all_ids), "manifest_test_count": manifest_validation["manifest_count"], "policy_coverage_percent": manifest_validation["coverage_percent"], "executed_test_count": total_tests, "duplicate_execution_count": len(duplicate_ids), "missing_execution_count": len(missing_ids), "unexpected_execution_count": len(unexpected_ids), "duplicate_test_ids": duplicate_ids, "missing_test_ids": missing_ids, "unexpected_test_ids": unexpected_ids, "process_sensitive_shared_worker_count": sum(1 for row in records if row.get("policy") != SAFE_SHARED_WORKER and len(row.get("test_ids", [])) != 1), "order_name": order_name, "random_seed": random_seed, "load_profile": load_profile, "policy_manifest_sha256": manifest_digest, "startup_calibration": calibration.to_dict(), "deadline_calibration": deadline_calibration.to_dict(), "group_admission_failure_count": sum(1 for row in records if row.get("reason") == "group_admission_budget_insufficient"), "groups": records, "passed": passed}, sort_keys=True))
    return passed


def run_functional_smoke() -> bool:
    names = [
        "tests.test_acceptance.AcceptanceTests.test_at_01",
        "tests.test_core.StateAndCheckpointTests.test_wfl_02_completion_requires_evaluator",
        "tests.test_rg.RegressionAttackTests.test_rg_01",
        "tests.test_r2_rg.R2RegressionTests.test_r2_rg_14",
        "tests.test_r3_rg.R3RegressionTests.test_r3_rg_17",
    ]
    suite = unittest.TestSuite(unittest.defaultTestLoader.loadTestsFromName(name) for name in names)
    return unittest.TextTestRunner(verbosity=1).run(suite).wasSuccessful()


def main() -> int:
    parser = argparse.ArgumentParser()
    group = parser.add_mutually_exclusive_group()
    group.add_argument("--tests-only", action="store_true")
    group.add_argument("--evidence-build", action="store_true")
    group.add_argument("--child-smoke", action="store_true")
    group.add_argument("--functional-smoke", action="store_true")
    group.add_argument("--test-worker", action="store_true", help=argparse.SUPPRESS)
    group.add_argument("--evidence", action="store_true", help="compatibility alias for --evidence-build")
    parser.add_argument("--order", choices=["default", "reverse", "random", "sensitive-first", "sensitive-last"], default="default")
    parser.add_argument("--seed", type=int)
    parser.add_argument("--load-profile", default="normal")
    args = parser.parse_args()
    if args.evidence or args.evidence_build:
        nesting = int(os.environ.get("EVIDENCE_NESTING_LEVEL", "0"))
        if nesting >= 1:
            print("EVIDENCE_NESTING_BLOCKED")
            return 3
        os.environ["EVIDENCE_NESTING_LEVEL"] = "1"
        from scripts.build_evidence import build
        return 0 if build() else 2
    if args.child_smoke:
        suite = unittest.defaultTestLoader.loadTestsFromName("tests.test_core.DocumentAndAgentTests")
        return 0 if unittest.TextTestRunner(verbosity=1).run(suite).wasSuccessful() else 1
    if args.functional_smoke:
        return 0 if run_functional_smoke() else 1
    if args.test_worker:
        return 0 if run_tests_worker() else 1
    if args.order == "random" and args.seed is None:
        parser.error("--order random requires --seed")
    return 0 if run_tests(args.order, args.seed, args.load_profile) else 1


if __name__ == "__main__":
    raise SystemExit(main())
