"""Bounded offline Galaxy52B producer/config evidence, not SystemMap RealStar48B."""
import hashlib,json,struct
from pathlib import Path
import pefile

scope={}
exec(Path('research/Extract-OriginalGalaxyAppearance.py').read_text().split('tables={}')[0],scope)
b=scope['b'];at=scope['at'];references=scope['references'];floats=scope['floats']
image=Path('artifacts/ship-model-reference/client-copy/EliteDangerous64.exe').read_bytes()
sha=hashlib.sha256(image).hexdigest()
if sha!='6891f70a021fa9f3a0e00458c284f48d1226e68ae7fc02ad48081aed47857e93':raise ValueError('Pinned client changed')
pe=pefile.PE(data=image,fast_load=True)
config=(295,14000)
weights_ptr=references[(config[0],config[1]+0x168)]
weights=floats(weights_ptr,2)
layer_ptr=references[(config[0],config[1]+0x170)]
count=struct.unpack_from('<I',b,at(config)+0x178)[0]
if count!=28:raise ValueError('Galaxy layer map changed')
layers=[list(struct.unpack_from('<BB',b,at((layer_ptr[0],layer_ptr[1]+i*2)))) for i in range(count)]
if weights!=[1,1] or layers!=[[i,i] for i in range(28)]:raise ValueError('Galaxy mask weights/layers changed')
constants=[]
for rva in (0x4DEE294,0x4DE1680):
    raw=image[pe.get_offset_from_rva(rva):pe.get_offset_from_rva(rva)+4]
    constants.append(dict(rva=hex(rva),raw=raw.hex(),value=struct.unpack('<f',raw)[0]))
decompiled=Path('artifacts/galaxy-query-research/power-outer-sources/decompiled')
sources=[]
for name in ('3a06740','3a15d90','3a25340','3a431c0','3a66600','3ab8300','3b32ee0','3b346b0','3a441a0','39fb140','3c10980','3c0f150'):
    candidates=list(Path('artifacts/galaxy-query-research').rglob('solo-'+name+'.c'))
    if candidates:
        source=candidates[0];sources.append(dict(rva='0x'+name,path=str(source),sha256=hashlib.sha256(source.read_bytes()).hexdigest()))
quad=[]
for rva in (0x54C7D80,0x54C7D70,0x54C7D60,0x54C7D60,0x50BD330,0x54C7D80):
    raw=pe.get_data(rva,16)
    quad.append(dict(rva=hex(rva),raw=raw.hex(),uvCorner=list(struct.unpack('<4f',raw))))
if [row['uvCorner'] for row in quad]!=[[0,1,-1,-1],[0,0,-1,1],[1,0,1,1],[1,0,1,1],[1,1,1,-1],[0,1,-1,-1]]:raise ValueError('Galaxy quad changed')
ctor=pe.get_data(0x3C01470,0x65)
if ctor[0x52]!=0xE8 or 0x3C01470+0x57+struct.unpack_from('<i',ctor,0x53)[0]!=0x3C10980:raise ValueError('Quad-init call changed')
result=dict(gameProcessAccess=False,gameCalls=0,networkRequests=0,gameImageSha256=sha,
    frozenSha256=hashlib.sha256(b).hexdigest(),configuration=dict(pool=295,offset=14000),
    weights=dict(field='0x168',pointer=weights_ptr,sourceFloats=weights,rendererFields=['0x9DC','0x9D8'],shaderInputs='POSITION2.xy'),
    arrayLayers=dict(field='0x170',pointer=layer_ptr,count=count,pairs=layers),
    gpuInstance=dict(producerRva='0x3A431C0',bytes=52,fields=[dict(offset=0,type='float3',meaning='actual compact worldXYZ'),
        dict(offset=12,type='float3',meaning='mask weights1,1,0'),dict(offset=24,type='float',meaning='mapped array layer'),
        dict(offset=28,type='half4',meaning='(1,constant,styleSize,constant); VS reads only .z'),
        dict(offset=36,type='float4',meaning='styleRGBA, no byte clamp')],halfUnusedConstants=constants),
    sourceChain=['3B3D9A0 registers base+80 by5F05DB4; renderer1E0 holds that interface',
        '3A15D90 subtracts20 to callback base+60/vtable552D6A8; callback0=3B346B0 fillsstyle',
        '3A66600 builds per-cell56B records;3AB8300 flips doublebufferDA8',
        '3A25340 reads activeD80/D88 records stride38 and calls3A431C0 withstyle+14'],
    quad=dict(chain=['3A441A0→39FB140(perviewport+8,+10,+18,+20,+28)','39FB140→3C01470(object+88,R8=6)',
        '3C01470→3C10980','3A1EBB0 uploads52B instances(confirmed imul0x34)','BackgroundStars VS consumes cornerZW*half(styleSize)'],
        ctorRva='0x3C01470',ctorBytes=ctor.hex(),vertices=quad,worldHalfExtent='IEEE half(styleSize)',
        pixelHalfExtent='half(styleSize)*camera.FocalLength/camera.Project(world).Depth',
        toolPixelMinimum=0),sources=sources,
    unclosed=['actual shared RGB multiplier cb1[90].y binding','full original blend and final HDR scene output',
        'special BackgroundBlackHole path','compact+59 extra multiplicity rendering'])
out=decompiled.parent/'galaxy-star-instance.json'
out.write_text(json.dumps(result,indent=2)+'\n')
print(json.dumps(dict(path=str(out),weights=weights,layers=count,unusedHalfConstants=constants),indent=2))
