#!/usr/bin/env bash
# generate_graphics_rules.sh
#
# Reads JSON gfx-config files and emits explicit Make rules for files that
# need special flags or segment handling.  Files that need no special
# treatment are left for the generic %.4bpp: %.png pattern rule in the
# Makefile.
#
# Usage: bash generate_graphics_rules.sh graphics/**/gfx.json ...
# Output: Make rules on stdout

set -euo pipefail

emit_rules() {
    local json="$1"
    local dir
    dir=$(dirname "$json")

    # Single jq call per JSON: emit one TSV line per file entry with all
    # resolved values.  Fields:
    #   gfx_filename  mwidth  mheight  oam  align  segments_json
    # segments_json is "null" when there are no segments, otherwise the
    # raw JSON array.
    jq -r '
        .defaults as $d |
        .files[]? |
        [
            .gfx_filename,
            ((.mwidth  // $d.mwidth  // 0) | tostring),
            ((.mheight // $d.mheight // 0) | tostring),
            ((.oam     // $d.oam     // false) | tostring),
            ((.align   // 0) | tostring),
            (if .segments then (.segments | tojson) else "null" end)
        ] | @tsv
    ' "$json" | while IFS=$'\t' read -r gfx_filename mwidth mheight oam align segments; do
        local stem="graphics/${dir#graphics/}/${gfx_filename}"
        local target="${stem}.4bpp"

        if [ "$segments" != "null" ]; then
            # --- Segmented file ---
            # Collect segment PNGs as prerequisites
            local seg_pngs
            seg_pngs=$(printf '%s' "$segments" | jq -r '.[].segfile' | while read -r sf; do
                printf '%s/%s.png ' "$dir" "$sf"
            done)

            printf '%s: %s%s\n' "$target" "$seg_pngs" "$json"

            # Emit a $(GFX) call for each segment
            local first=1
            printf '%s' "$segments" | jq -r '.[] | [.segfile, (.mwidth // 0 | tostring), (.mheight // 0 | tostring), (.oam // false | tostring)] | @tsv' | while IFS=$'\t' read -r segfile seg_mw seg_mh seg_oam; do
                local seg_png="${dir}/${segfile}.png"
                local seg_4bpp="${stem}_${segfile}.4bpp"
                local flags=""
                if [ "$seg_mw" != "0" ] && [ -n "$seg_mw" ]; then
                    flags="$flags -mwidth $seg_mw"
                fi
                if [ "$seg_mh" != "0" ] && [ -n "$seg_mh" ]; then
                    flags="$flags -mheight $seg_mh"
                fi
                if [ "$seg_oam" = "true" ]; then
                    flags="$flags -oam"
                fi
                printf '\t$(GFX) %s %s%s; \\\n' "$seg_png" "$seg_4bpp" "$flags"
            done

            # cat all segment .4bpp files together
            local seg_4bpps
            seg_4bpps=$(printf '%s' "$segments" | jq -r '.[].segfile' | while read -r sf; do
                printf '%s_%s.4bpp ' "$stem" "$sf"
            done)
            printf '\tcat %s> $@' "$seg_4bpps"

            # Alignment padding
            if [ "$align" != "0" ] && [ -n "$align" ]; then
                printf '; \\\n'
                printf '\tdd if=/dev/zero bs=32 count=%s >> $@ 2>/dev/null' "$align"
            fi
            printf '\n\n'
        else
            # --- Non-segmented file ---
            local flags=""
            if [ "$mwidth" != "0" ] && [ -n "$mwidth" ]; then
                flags="$flags -mwidth $mwidth"
            fi
            if [ "$mheight" != "0" ] && [ -n "$mheight" ]; then
                flags="$flags -mheight $mheight"
            fi
            if [ "$oam" = "true" ]; then
                flags="$flags -oam"
            fi

            # Skip if no special flags and no alignment — the generic
            # pattern rule in the Makefile handles this case.
            if [ -z "$flags" ] && { [ "$align" = "0" ] || [ -z "$align" ]; }; then
                continue
            fi

            printf '%s: %s.png %s\n' "$target" "$stem" "$json"
            printf '\t$(GFX) $< $@%s\n' "$flags"

            if [ "$align" != "0" ] && [ -n "$align" ]; then
                printf '\tdd if=/dev/zero bs=32 count=%s >> $@ 2>/dev/null\n' "$align"
            fi
            printf '\n'
        fi
    done
}

# --- Main ---
printf '# Auto-generated by %s — do not edit\n\n' "$(basename "$0")"

for json in "$@"; do
    # Only process gfx-config files
    if jq -e '.kind == "gfx-config"' "$json" > /dev/null 2>&1; then
        emit_rules "$json"
    fi
done
