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

die() { echo "ERROR: $*" >&2; exit 1; }
need_file() { [[ -f "$1" ]] || die "Missing file: $1"; }
need_dir() { [[ -d "$1" ]] || die "Missing directory: $1"; }

# ---------------------------
# Paths
# ---------------------------
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

ARMBIAN_BUILD_DIR="${ARMBIAN_BUILD_DIR:-/home/dmn/d100/armbian/build}"
WORKTREE_DIR="${WORKTREE_DIR:-$ARMBIAN_BUILD_DIR/cache/sources/linux-kernel-worktree/6.1__rk35xx__arm64}"

# Where to drop patches for Armbian build system
PATCH_DIR="${PATCH_DIR:-$ARMBIAN_BUILD_DIR/userpatches/kernel/rk35xx-vendor-6.1}"

# Sources (NOW next to the script)
SRC_DTS="${SRC_DTS:-$SCRIPT_DIR/rk3568-napi2.dts}"
OVERLAY_SRC_DIR="${OVERLAY_SRC_DIR:-$SCRIPT_DIR/overlays}"

# Kernel tree target locations
KERNEL_DTS_REL="arch/arm64/boot/dts/rockchip/rk3568-napi2.dts"
KERNEL_MAKEFILE_REL="arch/arm64/boot/dts/rockchip/Makefile"

KERNEL_OVERLAY_DIR_REL="${KERNEL_OVERLAY_DIR_REL:-arch/arm64/boot/dts/rockchip/overlay}"
KERNEL_OVERLAY_MAKEFILE_REL="${KERNEL_OVERLAY_MAKEFILE_REL:-$KERNEL_OVERLAY_DIR_REL/Makefile}"

# Patch names
PATCH_MAKEFILE_NAME="0001-rockchip-rk3568-napi2-makefile.patch"
PATCH_DTS_NAME="0100-rockchip-rk3568-napi2-dts.patch"

# ---------------------------
# Checks
# ---------------------------
need_dir "$ARMBIAN_BUILD_DIR"
need_dir "$WORKTREE_DIR"
need_dir "$PATCH_DIR"
need_file "$SRC_DTS"

cd "$WORKTREE_DIR"
git rev-parse --is-inside-work-tree >/dev/null 2>&1 || die "Not a git worktree: $WORKTREE_DIR"

KERNEL_DTS="$WORKTREE_DIR/$KERNEL_DTS_REL"
KERNEL_MAKEFILE="$WORKTREE_DIR/$KERNEL_MAKEFILE_REL"
need_file "$KERNEL_MAKEFILE"

KERNEL_OVERLAY_DIR="$WORKTREE_DIR/$KERNEL_OVERLAY_DIR_REL"
KERNEL_OVERLAY_MAKEFILE="$WORKTREE_DIR/$KERNEL_OVERLAY_MAKEFILE_REL"

mkdir -p "$PATCH_DIR"

echo "[1/7] Copy main DTS into kernel worktree"
install -m 0644 "$SRC_DTS" "$KERNEL_DTS"

echo "[2/7] Ensure main Makefile contains rk3568-napi2.dtb"
if ! grep -qE '(^|[[:space:]])rk3568-napi2\.dtb($|[[:space:]]|\\)' "$KERNEL_MAKEFILE"; then
  echo "      inserting dtb line into Makefile"
  if grep -qE '^subdir-y[[:space:]]*:=' "$KERNEL_MAKEFILE"; then
    sed -i '/^subdir-y[[:space:]]*:=/i dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-napi2.dtb\n' "$KERNEL_MAKEFILE"
  else
    printf "\n%s\n" 'dtb-$(CONFIG_ARCH_ROCKCHIP) += rk3568-napi2.dtb' >> "$KERNEL_MAKEFILE"
  fi
else
  echo "      already present"
fi
grep -q "rk3568-napi2.dtb" "$KERNEL_MAKEFILE" || die "Makefile still does not contain rk3568-napi2.dtb"

echo "[3/7] Create DTS-only patch (0100...)"
git reset -q
git add "$KERNEL_DTS_REL"
if ! git diff --cached --name-only | grep -qx "$KERNEL_DTS_REL"; then
  die "No staged DTS change. Did you modify $SRC_DTS?"
fi
PATCH_TMP_DTS="/tmp/${PATCH_DTS_NAME}"
git diff --cached > "$PATCH_TMP_DTS"
grep -q "$KERNEL_DTS_REL" "$PATCH_TMP_DTS" || die "DTS patch does not reference $KERNEL_DTS_REL"

echo "[4/7] Create Makefile patch only if Makefile changed (0001...)"
git reset -q
git add "$KERNEL_MAKEFILE_REL"
PATCH_TMP_MK="/tmp/${PATCH_MAKEFILE_NAME}"
if git diff --cached --name-only | grep -qx "$KERNEL_MAKEFILE_REL"; then
  git diff --cached > "$PATCH_TMP_MK"
  grep -q "rk3568-napi2.dtb" "$PATCH_TMP_MK" || die "Makefile patch does not include rk3568-napi2.dtb"
  echo "      Makefile patch generated: $PATCH_TMP_MK"
else
  echo "      Main Makefile not changed; will NOT overwrite existing $PATCH_MAKEFILE_NAME"
  rm -f "$PATCH_TMP_MK" || true
fi

echo "[5/7] Install main patch files into userpatches"
cp -v "$PATCH_TMP_DTS" "$PATCH_DIR/$PATCH_DTS_NAME"
if [[ -f "$PATCH_TMP_MK" ]]; then
  cp -v "$PATCH_TMP_MK" "$PATCH_DIR/$PATCH_MAKEFILE_NAME"
fi

echo "[6/7] Process overlays folder -> one patch per overlay"
if [[ -d "$OVERLAY_SRC_DIR" ]]; then
  shopt -s nullglob
  overlays=( "$OVERLAY_SRC_DIR"/*.dts )
  shopt -u nullglob

  if (( ${#overlays[@]} == 0 )); then
    echo "      No overlays (*.dts) found in: $OVERLAY_SRC_DIR"
  else
    mkdir -p "$KERNEL_OVERLAY_DIR"

    # Ensure overlay Makefile exists (some trees have it; create minimal if not)
    if [[ ! -f "$KERNEL_OVERLAY_MAKEFILE" ]]; then
      echo "      Overlay Makefile not found, creating minimal: $KERNEL_OVERLAY_MAKEFILE_REL"
      cat >"$KERNEL_OVERLAY_MAKEFILE" <<'EOF'
# Auto-created by napi2dts-custom.sh (for Armbian patches)
EOF
    fi

    # Detect which dtbo list variable is actually used by this overlay/Makefile
    # Prefer dtbo-y / dtbo-m (most common); fallback to first dtbo-$(...) assignment; else dtbo-y.
    if grep -qE '^[[:space:]]*dtbo-y[[:space:]]*\+?=' "$KERNEL_OVERLAY_MAKEFILE"; then
      DTBO_VAR="dtbo-y"
    elif grep -qE '^[[:space:]]*dtbo-m[[:space:]]*\+?=' "$KERNEL_OVERLAY_MAKEFILE"; then
      DTBO_VAR="dtbo-m"
    elif grep -qE '^[[:space:]]*dtbo-\$\([^)]+\)[[:space:]]*\+?=' "$KERNEL_OVERLAY_MAKEFILE"; then
      DTBO_VAR="$(grep -E '^[[:space:]]*dtbo-\$\([^)]+\)[[:space:]]*\+?=' "$KERNEL_OVERLAY_MAKEFILE" \
        | head -n1 | sed -E 's/^[[:space:]]*([^[:space:]]+)[[:space:]]*\+?=.*/\1/')"
    else
      DTBO_VAR="dtbo-y"
    fi
    echo "      Overlay Makefile dtbo list variable: $DTBO_VAR"

    n=200
    for src in "${overlays[@]}"; do
      base="$(basename "$src")"           # rk3568-can2.dts
      name="${base%.dts}"                # rk3568-can2
      dtbo="${name}.dtbo"

      dst_rel="$KERNEL_OVERLAY_DIR_REL/$base"
      dst_abs="$WORKTREE_DIR/$dst_rel"

      echo "      -> overlay: $base"
      install -m 0644 "$src" "$dst_abs"

      # Ensure overlay Makefile lists this dtbo (use detected variable)
      if ! grep -qE "(^|[[:space:]])${dtbo}($|[[:space:]]|\\)" "$KERNEL_OVERLAY_MAKEFILE"; then
        echo "         adding to overlay Makefile: $dtbo"
        printf "%s\n" "${DTBO_VAR} += ${dtbo}" >> "$KERNEL_OVERLAY_MAKEFILE"
      fi

      # One patch per overlay (overlay dts + overlay Makefile)
      git reset -q
      git add "$dst_rel" "$KERNEL_OVERLAY_MAKEFILE_REL"

      if [[ -z "$(git diff --cached --name-only)" ]]; then
        echo "         (no staged changes; skipping patch)"
        continue
      fi

      patch_name="$(printf "%04d-rockchip-overlay-%s.patch" "$n" "$name")"
      patch_tmp="/tmp/$patch_name"

      git diff --cached > "$patch_tmp"
      grep -q "$dst_rel" "$patch_tmp" || die "Overlay patch missing $dst_rel (unexpected)"

      cp -v "$patch_tmp" "$PATCH_DIR/$patch_name"
      ((n++))
    done
  fi
else
  echo "      Overlays dir not found: $OVERLAY_SRC_DIR"
  echo "      Create it next to the script: $SCRIPT_DIR/overlays/"
fi

echo "[7/7] Summary"
echo "  Script dir:          $SCRIPT_DIR"
echo "  Main DTS source:     $SRC_DTS"
echo "  Overlay sources dir: $OVERLAY_SRC_DIR"
echo "  Patch output dir:    $PATCH_DIR"
echo "  Main patch (DTS):    $PATCH_DIR/$PATCH_DTS_NAME"
if [[ -f "$PATCH_DIR/$PATCH_MAKEFILE_NAME" ]]; then
  echo "  Main patch (Makefile): $PATCH_DIR/$PATCH_MAKEFILE_NAME"
else
  echo "  Main patch (Makefile): (not created this run)"
fi
echo "  Overlay patches:     $PATCH_DIR/0200...-rockchip-overlay-*.patch (if overlays exist)"

