"""Blender GPU preferences setup for native animation render (-a).

Called as:
  blender --background scene.blend --python turntable_gpu_setup.py -a

Reads the intended cycles_device from the scene custom property set by
turntable_setup.py, then applies the matching GPU compute device preferences.
GPU preferences are user-level and not stored in .blend, so they must be
re-applied at render time.

After this script runs, Blender processes -a and renders all animation frames
natively — keeping the GPU scene (BVH, textures) loaded across all frames.
"""
import bpy

scene = bpy.context.scene
cycles_device = scene.get("_cycles_device", "gpu")
denoiser_override = scene.get("_denoiser_override", "")

if scene.render.engine != 'CYCLES':
    # EEVEE or other engine — no Cycles GPU preferences needed
    print(f"[turntable_gpu] engine={scene.render.engine} — no Cycles GPU setup needed")
elif cycles_device == "cpu":
    scene.cycles.device = 'CPU'
    print("[turntable_gpu] Using CPU (explicit override)")
else:
    gpu_found = False
    try:
        cycles_prefs = bpy.context.preferences.addons['cycles'].preferences
        for device_type in ('OPTIX', 'CUDA', 'HIP', 'ONEAPI'):
            try:
                cycles_prefs.compute_device_type = device_type
                cycles_prefs.get_devices()
                gpu_devs = [d for d in cycles_prefs.devices if d.type != 'CPU']
                if gpu_devs:
                    for d in gpu_devs:
                        d.use = True
                    scene.cycles.device = 'GPU'
                    gpu_found = True

                    # OptiX denoiser is fully GPU-native and faster than OIDN on NVIDIA.
                    # Fall back to OIDN (also GPU-accelerated) on CUDA/HIP.
                    if not denoiser_override:
                        if device_type == 'OPTIX':
                            try:
                                scene.cycles.denoiser = 'OPTIX'
                                print("[turntable_gpu] OptiX denoiser active (GPU-native)")
                            except Exception:
                                pass  # Keep OIDN
                    else:
                        try:
                            scene.cycles.denoiser = denoiser_override
                            print(f"[turntable_gpu] Denoiser override: {denoiser_override}")
                        except Exception:
                            pass

                    # Blender 4.x+: explicitly route OIDN through GPU path
                    try:
                        scene.cycles.denoising_use_gpu = True
                    except AttributeError:
                        pass  # Older Blender — OIDN uses GPU automatically when device=GPU

                    print(f"[turntable_gpu] Cycles GPU ({device_type}) — rendering {scene.frame_end - scene.frame_start + 1} frames")
                    break
            except Exception:
                continue
    except Exception:
        pass

    if not gpu_found:
        scene.cycles.device = 'CPU'
        print("[turntable_gpu] WARNING: GPU not found — falling back to CPU")

print(f"[turntable_gpu] Output: {scene.render.filepath}#### (frames {scene.frame_start}–{scene.frame_end})")
