from preflight import R,g,HEAD
import hashlib,json,os,shutil,signal,subprocess,tarfile,time
from pathlib import Path
assert not (R/'build-started.json').exists()
v=json.loads((R/'source-verify.json').read_text());assert v['tests']==2 and v['errors']==v['failures']==0
assert json.loads((R/'shared-trial.json').read_text())['stage']=='PASS'
assert g.sh(['git','-C',str(g.REPO),'rev-parse','HEAD']).strip()==HEAD
assert not g.sh(['git','-C',str(g.REPO),'status','--porcelain']).strip()
plan=json.loads((R/'plan.json').read_text());free=lambda:shutil.disk_usage(plan['docker_root']).free
assert free()>=15*1024**3
hashes={p:g.sha(g.REPO/p) for p in ('app/api/streams.py','app/stream_manager.py','docker/Dockerfile')}
digest=hashlib.sha256((HEAD+json.dumps(hashes,sort_keys=True)).encode()).hexdigest()
tag='contextra-analytics:rtsp-shared-05d525d-'+digest[:8]
assert subprocess.run(['docker','image','inspect',tag],capture_output=True).returncode!=0
snap=R/'snapshot';snap.mkdir(mode=0o700)
p=subprocess.Popen(['git','-C',str(g.REPO),'archive',HEAD],stdout=subprocess.PIPE)
with tarfile.open(fileobj=p.stdout,mode='r|') as archive:archive.extractall(snap,filter='data')
assert p.wait()==0
(R/'source.json').write_text(json.dumps(dict(head=HEAD,hashes=hashes,tag=tag),indent=2))
(R/'build-started.json').write_text(json.dumps(dict(build_count=1,tag=tag,disk_free=free())))
start=time.monotonic();reason=None
with (R/'build.log').open('x') as log:
    p=subprocess.Popen(['docker','build','-f','docker/Dockerfile','--target','app','-t',tag,'.'],cwd=snap,stdout=log,stderr=log,start_new_session=True,env=dict(os.environ,DOCKER_BUILDKIT='1'))
    while p.poll() is None:
        if time.monotonic()-start>1200 or free()<15*1024**3:
            reason='TIME_OR_DISK_CAP';os.killpg(p.pid,signal.SIGTERM)
            try:p.wait(15)
            except subprocess.TimeoutExpired:os.killpg(p.pid,signal.SIGKILL)
            break
        time.sleep(2)
    code=p.wait()
result=dict(tag=tag,returncode=code,abort_reason=reason,elapsed_s=time.monotonic()-start,disk_free=free())
if code==0:result['image_id']=json.loads(g.sh(['docker','image','inspect',tag]))[0]['Id']
(R/'build.json').write_text(json.dumps(result,indent=2));print(json.dumps(result));assert code==0 and reason is None
