import json
import os
from pathlib import Path
import shutil
import subprocess
import sys

ROOT = Path(__file__).resolve().parent.parent
REPO = Path('/workspace/contextra-analytics-runtime-lifecycle-refactor')
PRIOR = ROOT.parent/'2026-11-03_contextra-offline-full-prep_r01'
sys.path.insert(0, str(REPO))
from deployment_kit import bundle
from deployment_kit.core import KitError, sha256, write_json


def source_paths(commit):
    tracked = bundle.committed_files(REPO, commit)
    names = [n for n in tracked if n in ('ct-offline','tools/secure_bridge_tls.py',
             'control_sidecar/__init__.py','control_sidecar/config.py','control_sidecar/protocol.py')
             or n.startswith(('deployment_kit/','tools/icerti_offline/maintenance/','docs/deployment/'))]
    return sorted(n for n in names if not n.endswith(('.pyc','.env')) and '/test_' not in n)


def main():
    progress = json.loads((ROOT/'reports/r02/export-progress.json').read_bytes())
    assert progress['status'] == 'COMPLETE' and len(progress['completed']) == 6
    rows = progress['completed']
    delivery = ROOT/'Contextra_Offline_Preparation_20261103_r02'
    delivery.mkdir(mode=0o700)
    before = {Path(r['path']).name: (Path(r['path']).stat().st_dev, Path(r['path']).stat().st_ino,
                                   Path(r['path']).stat().st_size, Path(r['path']).stat().st_mtime_ns) for r in rows}
    # These are this run's new completed outputs only; the earlier incomplete run is untouched.
    (ROOT/'images/r02').rename(delivery/'images')
    locations = {r['path']: str(delivery/'images'/Path(r['path']).name) for r in rows}
    write_json(ROOT/'reports/locations.json', locations, new=True)
    after = {Path(r['path']).name: (Path(locations[r['path']]).stat().st_dev, Path(locations[r['path']]).stat().st_ino,
                                  Path(locations[r['path']]).stat().st_size, Path(locations[r['path']]).stat().st_mtime_ns) for r in rows}
    assert before == after
    write_json(ROOT/'reports/delivery-move-validation.json',dict(operation='same-filesystem rename',
               unchanged_inode_size_mtime=True,files=before,windows_transfer=False),new=True)
    commit = subprocess.check_output(['git','-C',str(REPO),'rev-parse','HEAD'],text=True).strip()
    paths = source_paths(commit)
    preview = delivery/'UNSEALED_PREVIEW'; preview.mkdir(mode=0o700)
    fingerprints = {}
    blocked = []
    tracked = bundle.committed_files(REPO, commit)
    for name in paths:
        src = REPO/name
        fingerprints[name] = sha256(src)
        try:
            bundle.checked_source(REPO, name, tracked[name])
        except KitError as exc:
            blocked.append(dict(path=name, code=exc.code))
        dst = preview/name; dst.parent.mkdir(parents=True,exist_ok=True)
        shutil.copyfile(src,dst); dst.chmod(0o600)
    spec = json.loads((PRIOR/'package-spec.pending.json').read_bytes())
    spec['release_id'] = 'test-demo-20261103-r02'
    spec['source_commit'] = commit
    spec['archives'] = ['images/'+Path(r['path']).name for r in rows]
    assets = {name:dict(source=locations[r['path']],sha256=r['sha256']) for name,r in zip(spec['archives'],rows)}
    write_json(ROOT/'reports/source-lock.json', fingerprints, new=True)
    write_json(ROOT/'reports/package-inputs.json',dict(spec=spec,source_paths=paths,assets=assets),new=True)
    write_json(ROOT/'reports/source-seal-gate.json',dict(status='BLOCKED_SOURCE_COMMIT' if blocked else 'READY',
               source_commit=commit, blocked=blocked, source_files=len(paths),
               preview_not_installable=True, package_manifest_created=False),new=True)
    write_json(delivery/'IMAGE_MANIFEST.json',dict(status='ARCHIVES_VERIFIED_NOT_SEALED_PACKAGE',
               images=[dict(role=r['role'],image=r['image'],path='images/'+Path(r['path']).name,
                            size=r['bytes'],sha256=r['sha256'],layers=r['validation']['layers']) for r in rows]),new=True)
    for name in ('cleanup-result.json','operator-validation.json','operator-validation-r02.json',
                 'operator-tests-r02.log','source-seal-gate.json','mount-order-correction.json','delivery-move-validation.json'):
        shutil.copyfile(ROOT/'reports'/name,delivery/name)
    for name in ('export-progress.json','export-after.json'):
        shutil.copyfile(ROOT/'reports/r02'/name,delivery/name)
    print(json.dumps(dict(delivery=str(delivery),archives=len(rows),total_gib=sum(r['bytes'] for r in rows)/2**30,
                         min_root_gib=min(r['min_root_free'] for r in rows)/2**30,blocked_source=blocked),ensure_ascii=False))


if __name__ == '__main__':
    main()
