"""Single bounded isolated suite; no live APIs or model inference."""
import contextlib
import io
import json
import os
from pathlib import Path
import shutil
import sys
import time

mode=sys.argv[1]
assert mode in ('dev','site')
root=Path('/work');source=root/'source' if mode=='dev' else root
previous=[root/(mode+'-pytest.log'),root/(mode+'-tests.json')]
if any(p.exists() for p in previous):
    archive=root/'test-history'/(mode+'-'+str(time.time_ns()));archive.mkdir(parents=True)
    for p in previous:
        if p.exists():shutil.copy2(p,archive/p.name)
if mode=='site':
    for name in ('fight_r5/notification.py','fall_config.py','fall_geometry.py','fall_scenario.py'):
        path=root/'app'/name;path.parent.mkdir(parents=True,exist_ok=True)
        raw=(Path('/opt/contextra/app')/name).read_bytes()
        if path.exists():assert path.read_bytes()==raw
        else:path.write_bytes(raw)
    shutil.copytree(root/'source/configs',root/'configs',dirs_exist_ok=True)
os.chdir(source)
sys.path[:0]=[str(source),str(source/'tests'),'/work','/opt/contextra']
if mode=='site':sys.path.append('/work/source')
import app.fall_r2.config as actual_config
expected_root=source/'app' if mode=='dev' else Path('/opt/contextra/app')
assert Path(actual_config.__file__).is_relative_to(expected_root)
import pytest

class Report:
    def __init__(self):self.passed=[];self.subtests=0;self.failed=[];self.errors=[];self.collected=0;self.deselected=[]
    def pytest_collection_modifyitems(self,session,config,items):
        skip=[i for i in items if any(i.nodeid.endswith(x) for x in known)]
        if skip:
            self.deselected=[i.nodeid for i in skip];items[:]=[i for i in items if i not in skip]
            config.hook.pytest_deselected(items=skip)
    def pytest_collection_finish(self,session):self.collected=len(session.items)
    def pytest_collectreport(self,report):
        if report.failed:self.errors.append(str(report.longrepr))
    def pytest_runtest_logreport(self,report):
        if report.failed:(self.failed if report.when=='call' else self.errors).append(report.nodeid)
        elif report.when=='call' and report.passed:
            if getattr(report,'context',None) is not None:self.subtests+=1
            else:self.passed.append(report.nodeid)

names=['test_fall_r2_config','test_fall_r2','test_fall_core','test_fall_boundaries','test_fall_skip_hold',
       'test_fall_integration','test_fight_r5','test_fight_notification','test_fight_notification_runtime',
       'test_event_cooldown','test_loitering_settings','test_output_settings']
known=['test_fall_integration.py::SettingsTests::test_fire_combination_no_save',
       'test_fall_integration.py::SettingsTests::test_roi_empty_aliases_and_independent_confidence',
       'test_output_settings.py::OutputSettingsAPI::test_running_patch_waits_for_old_worker_then_applies_once']
args=['-q','-p','no:cacheprovider','/work/test_migration.py',*[str(source/'tests'/(n+'.py')) for n in names]]
r=Report();buffer=io.StringIO()
with contextlib.redirect_stdout(buffer),contextlib.redirect_stderr(buffer):
    code=pytest.main(args,plugins=[r])
(root/(mode+'-pytest.log')).write_text(buffer.getvalue())
value=dict(exit_code=int(code),collected=r.collected,passed=len(r.passed),subtests_passed=r.subtests,failed=r.failed,errors=r.errors,
           excluded_baseline_failures=r.deselected,excluded_gpu_dependent_module='test_async_restart',mode=mode,
           application_source=actual_config.__file__)
(root/(mode+'-tests.json')).write_text(json.dumps(value,indent=2))
print(json.dumps(value))
raise SystemExit(code)
