// Schaeffler Still Render job type for Flamenco 3.x
// Pipeline: STEP -> STL (cadquery) -> Blender single-frame render

const JOB_TYPE = {
    label: "Schaeffler Still",
    settings: [
        { key: "step_path", type: "string", required: true,
          description: "Absolute path to STEP file" },
        { key: "output_path", type: "string", required: true,
          description: "Full path for output image (e.g. /shared/render.png)" },
        { key: "width", type: "int32", default: 1024,
          description: "Output width in pixels" },
        { key: "height", type: "int32", default: 1024,
          description: "Output height in pixels" },
        { key: "engine", type: "string", default: "cycles",
          description: "Blender render engine: cycles or eevee" },
        { key: "samples", type: "int32", default: 256,
          description: "Render samples" },
        { key: "stl_quality", type: "string", default: "low",
          description: "STL mesh quality: low or high" },
        { key: "part_colors_json", type: "string", default: "{}",
          description: "JSON dict mapping part names to hex colors" },
        { key: "transparent_bg", type: "bool", default: false,
          description: "Render with transparent background (PNG alpha)" },
        { key: "template_path", type: "string", default: "",
          description: "Path to .blend template file (empty = factory settings)" },
        { key: "target_collection", type: "string", default: "Product",
          description: "Blender collection name to import geometry into" },
        { key: "material_library_path", type: "string", default: "",
          description: "Path to material library .blend file" },
        { key: "material_map_json", type: "string", default: "{}",
          description: "JSON dict mapping part names to material names" },
        { key: "part_names_ordered_json", type: "string", default: "[]",
          description: "JSON array of STEP part names in solid order (for index-based matching)" },
        { key: "lighting_only", type: "bool", default: false,
          description: "Use template only for World/HDRI lighting; always auto-frame with computed camera" },
        { key: "cycles_device", type: "string", default: "auto",
          description: "Cycles compute device: auto (try GPU, fall back to CPU), gpu (force GPU), cpu (force CPU)" },
        { key: "shadow_catcher", type: "bool", default: false,
          description: "Enable Shadowcatcher collection from template and position plane under product (Cycles only)" },
        { key: "rotation_x", type: "float", default: 0.0,
          description: "Product rotation around X axis in degrees (render position)" },
        { key: "rotation_y", type: "float", default: 0.0,
          description: "Product rotation around Y axis in degrees (render position)" },
        { key: "rotation_z", type: "float", default: 0.0,
          description: "Product rotation around Z axis in degrees (render position)" },
        { key: "noise_threshold", type: "string", default: "",
          description: "Adaptive sampling noise threshold (empty = Blender default 0.01)" },
        { key: "denoiser", type: "string", default: "",
          description: "Cycles denoiser: OPTIX, OPENIMAGEDENOISE, or empty for auto" },
        { key: "denoising_input_passes", type: "string", default: "",
          description: "Denoising input passes: RGB, RGB_ALBEDO, RGB_ALBEDO_NORMAL, or empty for default" },
        { key: "denoising_prefilter", type: "string", default: "",
          description: "Denoising prefilter: NONE, FAST, ACCURATE, or empty for default" },
        { key: "denoising_quality", type: "string", default: "",
          description: "Denoising quality: HIGH, BALANCED, FAST, or empty for default (Blender 4.2+)" },
        { key: "denoising_use_gpu", type: "string", default: "",
          description: "Route OIDN denoising through GPU: 1, 0, or empty for auto" },
    ],
};

function compileJob(job) {
    const settings = job.settings;
    // Cache STL next to STEP file: {step_dir}/{step_stem}_{quality}.stl
    // This allows re-renders to skip the STEP→STL conversion step.
    const stepDir = settings.step_path.replace(/\/[^/]+$/, "");
    const stepBasename = settings.step_path.replace(/.*\//, "");
    const stepStem = stepBasename.replace(/\.[^.]+$/, "");
    const stlPath = stepDir + "/" + stepStem + "_" + settings.stl_quality + ".stl";

    // Task 1: Convert STEP to STL
    const convertTask = author.Task("convert-step", "misc");
    convertTask.addCommand(author.Command("exec", {
        exe: "{python}",
        args: [
            "/opt/flamenco/scripts/convert_step.py",
            settings.step_path,
            stlPath,
            settings.stl_quality,
        ],
    }));
    job.addTask(convertTask);

    // Task 2: Render single image with Blender
    const renderTask = author.Task("render-image", "blender");
    renderTask.addCommand(author.Command("exec", {
        exe: "{blender}",
        args: [
            "--background", "--python",
            "/opt/flamenco/scripts/still_render.py",
            "--",
            stlPath,
            settings.output_path,
            String(settings.width),
            String(settings.height),
            settings.engine,
            String(settings.samples),
            settings.part_colors_json,
            settings.transparent_bg ? "1" : "0",
            settings.template_path || "",
            settings.target_collection || "Product",
            settings.material_library_path || "",
            settings.material_map_json || "{}",
            settings.part_names_ordered_json || "[]",
            settings.lighting_only ? "1" : "0",
            settings.cycles_device || "auto",
            settings.shadow_catcher ? "1" : "0",
            String(settings.rotation_x || 0),
            String(settings.rotation_y || 0),
            String(settings.rotation_z || 0),
            settings.noise_threshold || "",
            settings.denoiser || "",
            settings.denoising_input_passes || "",
            settings.denoising_prefilter || "",
            settings.denoising_quality || "",
            settings.denoising_use_gpu || "",
        ],
    }));
    renderTask.addDependency(convertTask);
    job.addTask(renderTask);
}
