#!/usr/bin/env bash
set -euo pipefail

# convert.sh 1000 ./img/foo.png ./img/bar.jpg ...
# - Resizes so max(width,height) = maxDimension
# - Converts to PNG
# - Processes in parallel across CPU cores
# - PNG inputs are rewritten in place (temp -> replace)
# - Non-PNG inputs produce .png next to source, then source is deleted

usage() {
  echo "Usage: $0 <maxDimension> <file1> [file2 ...]" >&2
  exit 1
}

# ---- Args ----
[[ $# -ge 2 ]] || usage
maxDimension="$1"; shift
[[ "$maxDimension" =~ ^[0-9]+$ ]] || { echo "maxDimension must be an integer"; exit 1; }
files=( "$@" )

# ---- Checks ----
command -v ffmpeg >/dev/null 2>&1 || { echo "ffmpeg not found in PATH"; exit 1; }

# ---- Cores ----
if command -v nproc >/dev/null 2>&1; then
  CORES="$(nproc)"
elif [[ "$(uname -s)" == "Darwin" ]]; then
  CORES="$(sysctl -n hw.ncpu)"
else
  CORES=4
fi

process_one() {
  local in="$1"
  [[ -f "$in" ]] || { echo "Skip (not a file): $in" >&2; return 0; }

  local dir file base ext ext_lower final_out tmp_out
  dir="$(dirname "$in")"
  file="$(basename "$in")"
  base="${file%.*}"
  ext="${file##*.}"
  ext_lower="$(printf '%s' "$ext" | tr '[:upper:]' '[:lower:]')"

  final_out="${dir}/${base}.png"

  # Longer side -> maxDimension; keep aspect; -2 lets ffmpeg pick an even dimension
  local vf="scale='if(gte(iw,ih),${maxDimension},-2)':'if(gte(ih,iw),${maxDimension},-2)',format=rgba"

  if [[ "$ext_lower" == "png" ]]; then
    # Write to temp, then replace original in-place
    if tmp_out="$(mktemp "${dir}/.${base}.XXXXXX.tmp.png" 2>/dev/null)"; then
      :
    else
      tmp_out="${dir}/.${base}.$$.$RANDOM.tmp.png"
    fi

    if ffmpeg -hide_banner -loglevel error -nostdin -y \
      -i "$in" -vf "$vf" -c:v png "$tmp_out"; then
      mv -f -- "$tmp_out" "$in"
    else
      rm -f -- "$tmp_out" 2>/dev/null || true
      echo "Failed: $in" >&2
      return 1
    fi
  else
    # Convert to PNG next to source, then delete the original
    if ffmpeg -hide_banner -loglevel error -nostdin -y \
      -i "$in" -vf "$vf" -c:v png "$final_out"; then
      rm -f -- "$in"
    else
      rm -f -- "$final_out" 2>/dev/null || true
      echo "Failed: $in" >&2
      return 1
    fi
  fi
}

export -f process_one
export maxDimension

# ---- Parallel run ----
printf '%s\0' "${files[@]}" \
  | xargs -0 -n1 -P "${CORES}" -I{} bash -c 'process_one "$1"' _ {}
