"""Package a fully passing STEP3 assembly without changing historical evidence."""
import importlib.util
import json
import mmap
from pathlib import Path
import shutil
import subprocess
import sys
sys.dont_write_bytecode = True
OUT = Path(__file__).resolve().parent
ROOT = OUT.parents[3]
spec = importlib.util.spec_from_file_location('step3_capsule_producer',OUT/'run.py')
p = importlib.util.module_from_spec(spec)
spec.loader.exec_module(p)
spec = importlib.util.spec_from_file_location('step3_capsule_symbols',ROOT/'.spt/preserved/302/symbols/prepare_symbols.py')
s = importlib.util.module_from_spec(spec)
spec.loader.exec_module(s)
g = p.g


def identity(path, parser):
    with path.open('rb') as file, mmap.mmap(file.fileno(),0,access=mmap.ACCESS_READ) as data:
        return parser(data)


def artifact(path):
    return dict(path=str(path),bytes=path.stat().st_size,sha256=g.digest(path))


def main():
    receipts = {name:json.loads((OUT/name/'receipt.json').read_bytes()) for name in p.PHASES}
    for name, receipt in receipts.items():
        if receipt['status']!='passed' or receipt['driver_exit']!=0 or receipt['source_changes'] or receipt.get('finalization_error'):
            raise RuntimeError('nonpassing or mutated phase: '+name)
        if any(row['native_exit']!=0 for row in receipt['commands']):
            raise RuntimeError('nonzero native phase: '+name)
        for which in ('source_before','source_after'):
            if receipt[which]['head']!=p.f.r.HEAD or receipt[which]['diff_sha256']!=p.f.r.EMPTY_SHA256:
                raise RuntimeError('wrong or dirty assembly identity: '+name)
        if receipt['source_before']['source_map_sha256']!=receipts['pool-claim']['source_before']['source_map_sha256']:
            raise RuntimeError('source differs between phases: '+name)
    owner = json.loads((g.TARGET/'POOL-OWNER.json').read_bytes())
    if set(owner)!={'owner_tree','written_by'} or Path(owner['owner_tree']).resolve()!=g.TREE.resolve():
        raise RuntimeError('owned pool has not been released')
    version = (OUT/'version/version.stdout').read_text(encoding='utf-8').strip()
    if version!='spt 0.70.0':
        raise RuntimeError('unexpected CLI version: '+version)
    exe,pdb = OUT/'built-subjects/spt.exe',OUT/'built-subjects/spt.pdb'
    expected = receipts['build-jobs8']['built_subjects']['release/spt.exe']
    for source,key in ((exe,'exe_sha256'),(pdb,'pdb_sha256')):
        if g.digest(source)!=expected[key] or g.digest(g.TARGET/'release'/source.name)!=expected[key]:
            raise RuntimeError('built application changed during proof: '+source.name)
    pe,pi = identity(exe,s.pe_identity),identity(pdb,s.pdb_identity)
    cv = pe['codeview']
    if cv['guid']!=pi['guid'] or cv['age']!=pi['info_age'] or cv['age']!=pi['dbi_age'] or cv['name'].lower()!='spt.pdb':
        raise RuntimeError('application PE/PDB GUID or age mismatch')
    original = ROOT/'.spt/preserved/302/enlyzeam-symbols'
    historical = original/'manifest.json'
    if g.digest(historical)!='6431f18c6e54db4c4834d13a8b66c1c8a43d5c40c4e0fa7797b0960f73221978':
        raise RuntimeError('historical EN symbol provenance changed')
    os_manifest = json.loads(historical.read_bytes())
    if len(os_manifest['modules'])!=15:
        raise RuntimeError('exact fifteen EN OS modules required')
    capsule = ROOT/'.spt/preserved/302/artifacts-release-0611a058'
    capsule.mkdir()  # Never overwrite or reuse a partial capsule.
    symbols = capsule/'symbols'
    symbols.mkdir()
    shutil.copy2(exe,capsule/'spt.exe')
    shutil.copy2(pdb,capsule/'spt.pdb')
    shutil.copy2(pdb,symbols/'spt.pdb')
    bundle = []
    for module in os_manifest['modules']:
        source = Path(module['flat_path'])
        if not module['identity_match'] or g.digest(source)!=module['pdb_sha256']:
            raise RuntimeError('historical OS PDB mismatch: '+source.name)
        dest = symbols/source.name
        shutil.copy2(source,dest)
        actual = identity(dest,s.pdb_identity)
        os_cv = module['pe']['codeview']
        if actual!=module['pdb_identity'] or actual['guid']!=os_cv['guid'] or actual['dbi_age']!=os_cv['age'] or actual['info_age']<os_cv['age'] or g.digest(dest)!=module['pdb_sha256']:
            raise RuntimeError('OS PDB copy or identity mismatch: '+source.name)
        bundle.append(dict(module=module['module'],**artifact(dest),pdb_identity=actual,codeview=os_cv))
    if identity(symbols/'spt.pdb',s.pdb_identity)!=pi or g.digest(symbols/'spt.pdb')!=expected['pdb_sha256']:
        raise RuntimeError('application bundle copy mismatch')
    bundle.append(dict(module='spt.exe',**artifact(symbols/'spt.pdb'),pdb_identity=pi,codeview=cv))
    if len(bundle)!=16 or len({Path(row['path']).name.lower() for row in bundle})!=16:
        raise RuntimeError('sixteen distinct symbols required')
    os_only = Path(os_manifest['os_only_manifest']['path'])
    if g.digest(os_only)!=os_manifest['os_only_manifest']['sha256']:
        raise RuntimeError('OS-only manifest provenance mismatch')
    shutil.copy2(os_only,symbols/'manifest.os-only.json')
    g.save(symbols/'manifest.json',dict(scope='Exact ENLYZEAM Windows19045.6466 OS symbols plus STEP3 application; not HFENDULEAM OS symbols',build_commit=p.f.r.HEAD,modules=bundle,historical_manifest=artifact(historical),immutable_os_manifest=artifact(symbols/'manifest.os-only.json')))
    delta = subprocess.run(['git','diff','--stat',p.FIX,p.f.r.HEAD],cwd=g.TREE,capture_output=True,text=True,check=True).stdout
    if g.digest(capsule/'spt.exe')!=expected['exe_sha256'] or g.digest(capsule/'spt.pdb')!=expected['pdb_sha256']:
        raise RuntimeError('capsule application copy mismatch')
    result = dict(build_commit=p.f.r.HEAD,fix_commit=p.FIX,assembly_branch=p.f.r.BRANCH,fix_branch='fix/302-meet-offload',profile=p.f.r.PROFILE,build_profile='release+line-tables',cli_version=version,broker_version='0.70.0',producer_host=g.os.environ.get('COMPUTERNAME'),path_scope='Producer-local only; no ENLYZEAM transfer or lifecycle action',exe=artifact(capsule/'spt.exe'),pdb=artifact(capsule/'spt.pdb'),release_pair_identity=dict(pe=pe,pdb=pi,guid_match=True,info_age_match=True,dbi_age_match=True),symbol_pairing_reviewed=True,symbol_bundle=artifact(symbols/'manifest.json'),symbol_count=16,diagnostic_delta_from_fix=delta,proofs={name:artifact(OUT/name/'receipt.json') for name in p.PHASES},local_boundary_proof=receipts['meet-diag']['local_boundary_proof'],authority='UF6PGKRW',upstream_gate=dict(accepted='gate-231-712c987f/run2',void='run1 (Doyle-reported VOID)',void_reason='Tests overlapped running Windows CI; precondition miss'),released_pool=str(g.TARGET),packager=artifact(Path(__file__)),field_acceptance='PENDING Doyle/operator restage, Hertz STEP3 capture, local and remote rc checks')
    result['superseded_build'] = dict(authority='MFTKRX7V',disposition=artifact(OUT/'jobs2-disposition.json'),stop_request=artifact(OUT/'jobs8-stop-request.json'),receipt=artifact(OUT/'build/receipt.json'),interpretation='Operator-authorized jobs2 to jobs8 restart; excluded from the passing active proof phases, never erased or relabeled as a successful build')
    g.save(capsule/'manifest.json',result)
    g.save(OUT/'capsule-identity.json',artifact(capsule/'manifest.json'))
    print(json.dumps(artifact(capsule/'manifest.json'),indent=2))


if __name__=='__main__':
    main()
