"""Engine configuration and final render call for blender_render.py."""
import sys
from typing import Callable

import bpy  # type: ignore[import]

from _blender_gpu import configure_engine


def configure_and_render(args, early_gpu_type, use_template: bool, lap_fn: Callable[[str], None]) -> None:
    """Configure render engine, colour management, resolution, then render.

    Reads engine, samples, device, denoiser, and output settings from args.
    lap_fn is called with label strings at timing checkpoints.
    """
    scene = bpy.context.scene
    configure_engine(
        scene, args.engine, args.samples, args.cycles_device, early_gpu_type,
        args.noise_threshold, args.denoiser,
        args.denoising_input_passes, args.denoising_prefilter,
        args.denoising_quality, args.denoising_use_gpu,
    )

    if not use_template:
        scene.view_settings.view_transform = "Standard"
        scene.view_settings.exposure        = 0.0
        scene.view_settings.gamma           = 1.0
        try:
            scene.view_settings.look = "None"
        except Exception:
            pass

    scene.render.resolution_x               = args.width
    scene.render.resolution_y               = args.height
    scene.render.resolution_percentage      = 100
    scene.render.image_settings.file_format = "PNG"
    scene.render.filepath                   = args.output_path
    scene.render.film_transparent           = args.transparent_bg

    if scene.render.engine == "CYCLES":
        cprefs = bpy.context.preferences.addons["cycles"].preferences
        print(
            f"[blender_render] VERIFY: engine={scene.render.engine}, "
            f"cycles.device={scene.cycles.device}, "
            f"compute_device_type={cprefs.compute_device_type}, "
            f"gpu_devices={[(d.name, d.type, d.use) for d in cprefs.devices if d.type != 'CPU']}",
            flush=True,
        )

    lap_fn("pre_render_setup")
    print(f"[blender_render] Rendering → {args.output_path}  (Blender {bpy.app.version_string})", flush=True)
    sys.stdout.flush()
    bpy.ops.render.render(write_still=True)
    print("[blender_render] render done.", flush=True)
    lap_fn("gpu_render")
