from pathlib import Path
import os,sys,re,subprocess,json,time,fcntl
root=Path('/home/jakub/devel/escapistsrereintroduced');sys.path.insert(0,str(root/'tools'))
from headless_game import assert_prefix_idle,cleanup_owned_run
compat=Path('/tmp/erri-headless-compat');lock=(compat/'.erri-workbench.lock').open('a');fcntl.flock(lock,fcntl.LOCK_EX|fcntl.LOCK_NB);assert_prefix_idle(compat)
steam=Path.home()/'.local/share/Steam';wb=steam/'steamapps/common/Arma Reforger Tools/Workbench';proton=steam/'steamapps/common/Proton - Experimental/proton'
profile=Path('/tmp')/sys.argv[1];profile.mkdir();addons=profile/'addons';addons.mkdir()
(addons/'ArmaReforger').symlink_to(steam/'steamapps/common/Arma Reforger/addons/data',target_is_directory=True)
installed=steam/'steamapps/compatdata/1874880/pfx/drive_c/users/steamuser/Documents/My Games/ArmaReforger/addons'
projects={}
for p in installed.glob('*/addon.gproj'):
 t=p.read_text();g=re.search(r'GUID "([A-Fa-f0-9]+)"',t)
 if g:projects[g[1].upper()]=(p,re.findall(r'"([A-Fa-f0-9]{16})"',t.split('Dependencies',1)[-1]) if 'Dependencies' in t else [])
pending=['595F2BF2F44836FB','629B2BA37EFFD577','5E524E4FEECCA92B','65930CB4CD0237B2'];seen=set()
while pending:
 g=pending.pop()
 if g in seen or g=='58D0FB3206B6F859':continue
 seen.add(g);p,deps=projects[g];(addons/('Dependency_'+g)).symlink_to(p.parent,target_is_directory=True);pending.extend(deps)
# Compile with the currently installed dependency manifests, not the obsolete
# historical smoke-test manifest hashes. No addon files are changed.
env=os.environ.copy();env.update(STEAM_COMPAT_DATA_PATH=str(compat),STEAM_COMPAT_CLIENT_INSTALL_PATH=str(steam),WINEPREFIX=str(compat/'pfx'),PULSE_SINK='erri_tests_silent',PULSE_PROP='application.id=org.escapistsrereintroduced.tests')
cmd=['gamescope','--backend','headless','-W','1280','-H','720','-w','1280','-h','720','-r','30','--',str(proton),'run',str(wb/'ArmaReforgerWorkbenchSteamDiag.exe'),'-gproj','Z:'+str(root/'addons/core/addon.gproj'),'-addonsDir','Z:'+str(root/'addons'),'-profile','Z:'+str(profile),'-logconsole','-wbModule=WorldEditor','-load','Worlds/ERR_Everon.ent','-plugin=ERR_ValidateWorldPlugin','-errPlay','1','-errHeldMapProbe','1','-noSound','-noThrow','-disableCrashReporter']
if len(sys.argv)>2 and sys.argv[2]=='signal':cmd.extend(['-errRescueSignalOnly','1'])
result='timeout';text='';start=time.monotonic();injected=set()
with (profile/'launch.log').open('w') as log:
 child=subprocess.Popen(cmd,cwd=wb,env=env,stdout=log,stderr=subprocess.STDOUT,start_new_session=True)
 try:
  while time.monotonic()-start<300:
   logs=sorted((profile/'logs').glob('*/console.log'))
   if logs:text=logs[-1].read_text(errors='replace')
   for marker,key,count in [('RIGHT','Right','1'),('DOWN','Down','1'),('DOUBLE','m','2'),('SINGLE','m','1'),('STORED','m','2')]:
    if marker not in injected and 'ERR HELD MAP KEY '+marker+' READY' in text:
     subprocess.run([sys.executable,'/tmp/err-private-map-key.py',str(profile/'launch.log'),key,count],check=True)
     injected.add(marker)
   if 'Can\'t compile' in text:result='compile-failed';break
   if 'ERR HELD MAP COMPLETE' in text:result='passed';break
   if 'ERR HELD MAP FAIL:' in text:result='probe-failed';break
   if child.poll() is not None:result='process-exited';break
   time.sleep(.5)
 finally:cleanup=cleanup_owned_run(child,proton,env,compat)
(profile/'result.json').write_text(json.dumps({'result':result,'cleanup':cleanup},indent=2))
print(result);print('\n'.join(l for l in text.splitlines() if 'SCRIPT    (E)' in l or 'ERR HELD MAP' in l or 'ERRM_Map' in l or 'MatUV' in l))
