"""Turn an Astra kit job's material shelf into the game shelf: PNG/JPG maps -> KTX2 (ETC1S, mipmapped; colour maps sRGB,
others linear) + our materials.json ({materials: {Name: {base, normal, orm, height?, tile, ...}}}).
usage: python3 tools/kit_shelf.py <job_dir> <out_kit_dir>     (also copies kit.glb + kit.json)"""
import glob, json, os, shutil, subprocess, sys
TOKTX = glob.glob(os.path.expanduser('~/.local/opt/KTX-Software-*/bin/toktx'))[0]
LIB = os.path.join(os.path.dirname(os.path.dirname(TOKTX)), 'lib')
job, out = sys.argv[1], sys.argv[2]
os.makedirs(f'{out}/materials', exist_ok=True)
src = json.load(open(f'{job}/materials.json'))
mats = src.get('materials', src)
items = mats.items() if isinstance(mats, dict) else [(m['name'], m) for m in mats]
res = {}
for name, m in items:
    d = f'{job}/materials/{name}'
    if not os.path.isdir(d):
        print('no folder for', name); continue
    entry = {'tile': m.get('tile_size_metres') or m.get('tile_m') or m.get('tile') or 1.0}
    maps = dict(m.get('maps') or {}); maps.setdefault('Height', m.get('height_map'))
    for key, stem, srgb in (('base', 'BaseColor', True), ('normal', 'Normal', False), ('orm', 'ORM', False), ('height', 'Height', False)):
        f = os.path.join(job, maps[stem]) if maps.get(stem) else next(iter(glob.glob(f'{d}/{stem}.*')), None)
        if f and not os.path.exists(f): f = None
        if not f:
            continue
        dst = f'{out}/materials/{name}_{stem}.ktx2'
        opts = ['--t2', '--encode', 'etc1s', '--clevel', '4', '--qlevel', '255', '--genmipmap',
                *(['--assign_oetf', 'srgb'] if srgb else ['--assign_oetf', 'linear', '--assign_primaries', 'none'])]
        tmp = f
        if not f.endswith('.png'):
            from PIL import Image
            tmp = f'/tmp/kitshelf-{name}-{stem}.png'; Image.open(f).save(tmp)
        subprocess.run([TOKTX, *opts, '--threads', '4', dst, tmp], check=True, env={**os.environ, 'LD_LIBRARY_PATH': LIB})
        entry[key] = f'materials/{name}_{stem}.ktx2'
    for k, src_k in (('roughness', 'roughness_factor'), ('metalness', 'metalness_factor'), ('transparent', 'transparent'), ('opacity', 'opacity'), ('emissive', 'emissive_factor'), ('emissive_strength', 'emissive_strength')):
        if src_k in m: entry[k] = m[src_k]
    if 'height' in entry or m.get('displacement_scale_metres'):
        entry['displacement'] = {'scale': m.get('displacement_scale_metres', 0.105), 'bias': m.get('displacement_bias_metres', 0.006)}
    if 'glass' in name.lower():
        entry.setdefault('transparent', True)
    res[name] = entry
json.dump({'materials': res, 'source': os.path.basename(os.path.abspath(job))}, open(f'{out}/materials.json', 'w'), indent=1)
shutil.copy(f'{job}/kit.glb', f'{out}/kit.glb')
kj = json.load(open(f'{job}/kit.json')); kj.setdefault('file', 'kit.glb'); json.dump(kj, open(f'{out}/kit.json', 'w'), indent=1)
print('shelf:', {k: sorted(v) for k, v in res.items()})
