from ops import *

baseline = json.loads((HERE/'baseline.json').read_text())
paths = cmd(['git','-C',str(REPO),'ls-files','app','control_sidecar']).splitlines()
paths += cmd(['git','-C',str(REPO),'ls-files','--others','--exclude-standard','app','control_sidecar']).splitlines()
hashes = {p:hashlib.sha256((REPO/p).read_bytes()).hexdigest() for p in sorted(set(paths)) if (REPO/p).is_file()}
digest = hashlib.sha256(json.dumps(hashes,sort_keys=True).encode()).hexdigest()[:10]
snapshot = HERE/('image-'+digest)
snapshot.mkdir(mode=0o700)
for p in hashes:
    dst = snapshot/p
    dst.parent.mkdir(parents=True,exist_ok=True)
    shutil.copyfile(REPO/p,dst)
    dst.chmod(0o644)
images = {}
for key, container, source, dest in (
    ('analytics','contextra-analytics-1','app','/opt/contextra/app'),
    ('sidecar','contextra-ai-control-sidecar-1','control_sidecar','/opt/bridge/control_sidecar')):
    base = baseline['containers'][container]['image']
    tag = f'contextra-{key}:crowd-events-{digest}'
    dockerfile = snapshot/(key+'.Dockerfile')
    dockerfile.write_text(f'FROM {base}\nCOPY {source}/ {dest}/\n')
    assert shutil.disk_usage('/').free > 15*1024**3
    save(key+'-build-intent-'+digest+'.json',dict(base=base,tag=tag,hashes=hashes))
    with (HERE/(key+'-build-'+digest+'.log')).open('x') as log:
        proc = subprocess.Popen(['docker','build','--pull=false','--network=none','--memory=2g',
            '--cpu-period=100000','--cpu-quota=200000','-f',str(dockerfile),'-t',tag,str(snapshot)],
            env=dict(os.environ,DOCKER_BUILDKIT='0'),stdout=log,stderr=log)
        start = time.monotonic()
        while proc.poll() is None:
            if time.monotonic()-start > 180 or shutil.disk_usage('/').free < 15*1024**3:
                proc.terminate(); proc.wait(20)
                raise RuntimeError('BUILD_BOUND')
            time.sleep(1)
    assert proc.returncode == 0, key+' build failed'
    image = json.loads(cmd(['docker','image','inspect',tag]))[0]['Id']
    images[key] = dict(tag=tag,id=image,base=base)
save('images-'+digest+'.json',dict(images=images,hashes=hashes))
print(json.dumps(images),flush=True)
