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

ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
BOARD_DIR="$(cd "${ROOT_DIR}/.." && pwd)"
DEMO_BASE="${BOARD_DIR}/official-demo/examples/Arduino-v3.3.5"
MODE="${1:-widgets}"
PORT="${PORT:-}"
FQBN="${FQBN:-esp32:esp32:esp32s3:USBMode=hwcdc,CDCOnBoot=cdc,UploadSpeed=921600,CPUFreq=240,FlashMode=dio,FlashSize=16M,PartitionScheme=app3M_fat9M_16MB,PSRAM=opi}"
BUILD_DIR="${BUILD_DIR:-${ROOT_DIR}/.arduino-build/build-${MODE}}"
OUT_DIR="${OUT_DIR:-${ROOT_DIR}/.arduino-build/out-${MODE}}"

detect_port() {
  local detected
  detected="$(arduino-cli board list 2>/dev/null | awk '/\/dev\/tty(ACM|USB)/ {print $1; exit}')"
  if [[ -n "${detected}" ]]; then
    echo "${detected}"
    return 0
  fi

  for candidate in /dev/ttyACM* /dev/ttyUSB*; do
    if [[ -e "${candidate}" ]]; then
      echo "${candidate}"
      return 0
    fi
  done

  return 1
}

case "${MODE}" in
  hello) SKETCH_DIR="${DEMO_BASE}/examples/01_HelloWorld" ;;
  widgets) SKETCH_DIR="${DEMO_BASE}/examples/05_LVGL_Widgets" ;;
  audio) SKETCH_DIR="${DEMO_BASE}/examples/07_ES8311" ;;
  simple) SKETCH_DIR="${ROOT_DIR}/simple_av_test" ;;
  argon2) SKETCH_DIR="${ROOT_DIR}/argon2_sd_test" ;;
  homeserver-ui) SKETCH_DIR="${ROOT_DIR}/shine_homeserver_main" ;;
  shine-homeserver-main) SKETCH_DIR="${ROOT_DIR}/shine_homeserver_main" ;;
  shine-homeserver-ui-main) SKETCH_DIR="${ROOT_DIR}/shine_homeserver_main" ;;
  legacy-homeserver-ui) SKETCH_DIR="${ROOT_DIR}/shine_homeserver_ui" ;;
  text-test) SKETCH_DIR="${ROOT_DIR}/text_render_test" ;;
  gfx-text-test) SKETCH_DIR="${ROOT_DIR}/test_sketches/gfx_text_render_test" ;;
  gfx-layout-test) SKETCH_DIR="${ROOT_DIR}/test_sketches/gfx_button_layout_test" ;;
  lvgl-basic-test) SKETCH_DIR="${ROOT_DIR}/test_sketches/lvgl_basic_test" ;;
  lvgl-interaction-test) SKETCH_DIR="${ROOT_DIR}/test_sketches/lvgl_interaction_test" ;;
  lvgl-touch-debug-test) SKETCH_DIR="${ROOT_DIR}/test_sketches/lvgl_touch_debug_test" ;;
  lvgl-official-based-test) SKETCH_DIR="${ROOT_DIR}/test_sketches/lvgl_official_based_test" ;;
  lvgl-subserver-touch-test) SKETCH_DIR="${ROOT_DIR}/test_sketches/lvgl_subserver_touch_test" ;;
  lvgl-russian-font-test) SKETCH_DIR="${ROOT_DIR}/test_sketches/lvgl_russian_font_test" ;;
  lvgl-nav-minimal-test) SKETCH_DIR="${ROOT_DIR}/shine_homeserver_main" ;;
  *)
    echo "Unknown mode: ${MODE}" >&2
    echo "Use one of: hello, widgets, audio, simple, argon2, homeserver-ui, shine-homeserver-main, shine-homeserver-ui-main, legacy-homeserver-ui, text-test, gfx-text-test, gfx-layout-test, lvgl-basic-test, lvgl-interaction-test, lvgl-touch-debug-test, lvgl-official-based-test, lvgl-subserver-touch-test, lvgl-russian-font-test" >&2
    exit 2
    ;;
esac

if [[ -z "${PORT}" ]]; then
  if ! PORT="$(detect_port)"; then
    echo "Failed to auto-detect ESP32 port. Set PORT=/dev/ttyACM0 ./burn.sh ${MODE}" >&2
    exit 3
  fi
fi

echo "== Mode:    ${MODE}"
echo "== Sketch:  ${SKETCH_DIR}"
echo "== Port:    ${PORT}"
echo "== FQBN:    ${FQBN}"

mkdir -p "${BUILD_DIR}" "${OUT_DIR}"

compile_args=(
  --fqbn "${FQBN}"
  --build-path "${BUILD_DIR}"
  --output-dir "${OUT_DIR}"
  --library "${DEMO_BASE}/libraries/GFX_Library_for_Arduino"
  --library "${DEMO_BASE}/libraries/SensorLib"
  --library "${DEMO_BASE}/libraries/XPowersLib"
  --library "${DEMO_BASE}/libraries/lvgl"
  --library "${DEMO_BASE}/libraries/Mylibrary"
  "${SKETCH_DIR}"
)

echo "== Compile: fast incremental build"
if ! arduino-cli compile "${compile_args[@]}"; then
  echo "== Compile: fast build failed, retrying clean build"
  arduino-cli compile --clean "${compile_args[@]}"
fi

arduino-cli upload \
  -p "${PORT}" \
  --fqbn "${FQBN}" \
  --input-dir "${OUT_DIR}" \
  "${SKETCH_DIR}"

echo
echo "== Done."
