#!/bin/bash

if [ "$(id -u)" -ne 0 ]; then
  echo "This script must be run as root. Try 'sudo $0'"
  exit 1
fi

calc_wt_size() {
  # NOTE: it's tempting to redirect stderr to /dev/null, so supress error 
  # output from tput. However in this case, tput detects neither stdout or 
  # stderr is a tty and so only gives default 80, 24 values
  WT_HEIGHT=18
  WT_WIDTH=$(tput cols)

  if [ -z "$WT_WIDTH" ] || [ "$WT_WIDTH" -lt 60 ]; then
    WT_WIDTH=80
  fi
  if [ "$WT_WIDTH" -gt 178 ]; then
    WT_WIDTH=120
  fi
  WT_MENU_HEIGHT=$((WT_HEIGHT - 7))
}

msgbox() {
  dialog --title "$TITLE" --msgbox "$1" "$WT_HEIGHT" "$WT_WIDTH"
}

infobox () {
  dialog --title "$TITLE" --infobox "$1" "$WT_HEIGHT" "$WT_WIDTH"
}

fail() {
  msgbox "$1"
  exit 255
}

flash_loop () {
  local COUNT=0
  infobox "Attempting to flash EEPROM...\n\nEnsure write protect pads are shorted, as described in the documentation.\n\n$URL"
  while ! "$EEPFLASH" -y -w -f="$EEPPATH/$EEPFILE" -t=24c32 >> "$DBGFILE" 2>&1; do
    if [ "$COUNT" -ge 120 ]; then
      return 255
    fi
    COUNT=$((COUNT +1))
    sleep 1
  done
  return 0
}

cleanup () {
  status="$?"
  clear
  if [ "$status" -eq 0 ]; then
    rm -f "$DBGFILE"
  else
    echo "When reporting issues with this script, please attach $DBGFILE"
  fi
  rm -f "$TMPFILE"
}

calc_wt_size

TITLE="Raspberry Pi Audio Board Flashing Tool (rpi-audio-flash)"
URL="http://rptl.io/updating-audio-firmware"
EEPFLASH="/usr/bin/eepflash.sh"
EEPPATH="/usr/share/rpi-audio-utils"
trap 'cleanup' EXIT

if ! dialog --title "$TITLE" --defaultno --yesno \
    "This tool is intended to be used with unprogrammed Raspberry Pi Audio boards only.\n\nIncorrect usage may damage your hardware.\n\nPlease refer to $URL\n\nWould you like to continue?" \
    "$WT_HEIGHT" "$WT_WIDTH"; then
  exit 0
fi

DBGFILE="$(mktemp -t rpi-audio-XXXXXXXXXX.log)"
TMPFILE="$(mktemp -t rpi-audio-XXXXXXXXXX.eep)"
chmod a+r "$DBGFILE"
if ! "$EEPFLASH" -y -r -f="$TMPFILE" -t=24c32 >> "$DBGFILE" 2>&1; then
  fail "Failed to detect an EEPROM device."
fi
EEPSIZE="$(od "$TMPFILE" -j8 -N4 -tu4 -An | tr -d ' \n')"
EEPCSUM="$(head -c "$EEPSIZE" "$TMPFILE" | md5sum | tr -d ' \n-')"

FOUND=0
for ADDR in 4c 1a; do
  if [ -d "/sys/bus/i2c/devices/1-00$ADDR" ]; then
    FOUND=1
    break
  fi
  if ! [ -c  /dev/i2c-1 ]; then
    dtparam i2c_arm
    sleep 1
  fi
  if i2cget -y 1 "0x$ADDR" 0 b >> "$DBGFILE" 2>&1; then
    FOUND=1
    break
  fi
done

if [ "$FOUND" -eq 0 ]; then
  fail "Failed to detect a DAC device."
fi

case "$EEPCSUM" in
  f57fc4879e93a76f970c527721eafeb9|4f7363bb39bc2cde1825e3f3da4fc0bb)
    DETECTED="Raspberry Pi Codec Zero pHAT"
    ;;
  b40486e4090de6bec68a9730b842a5c0|f2d5d6b60151fb49599e5c77b6716b14)
    DETECTED="Raspberry Pi DAC+ HAT"
    ;;
  2901b3f50ac47f842eb94d157f4480fa|143a2729629b0baddc4b68c1a862fc8b)
    DETECTED="Raspberry Pi DAC Pro HAT"
    ;;
  5cc904beacc9b8d4d02e72e474449927|be0a7c7fce2f324f13700bfed27a6b5f)
    DETECTED="Raspberry Pi DigiAMP+ HAT"
    ;;
  *)
    DETECTED="None"
    ;;
esac

if [ "$DETECTED" != "None" ]; then
  msgbox "Detected a programmed $DETECTED."
  exit 0
fi

if ! TYPE=$(dialog --title "$TITLE" \
    --menu "Select your hardware" "$WT_HEIGHT" "$WT_WIDTH" "$WT_MENU_HEIGHT" \
    "1" "Raspberry Pi Codec Zero pHAT" \
    "2" "Raspberry Pi DAC+ HAT" \
    "3" "Raspberry Pi DAC Pro HAT" \
    "4" "Raspberry Pi DigiAMP+ HAT" \
    3>&1 1>&2 2>&3); then
  exit 0
fi

case "$TYPE" in
  1)
    EEPFILE=rpi-codeczero.eep
    OVERLAY=rpi-codeczero
    BOARD="Raspberry Pi Codec Zero pHAT"
    ;;
  2)
    EEPFILE=rpi-dacplus.eep
    OVERLAY=rpi-dacplus
    BOARD="Raspberry Pi DAC+ HAT"
    ;;
  3)
    EEPFILE=rpi-dacpro.eep
    OVERLAY=rpi-dacpro
    BOARD="Raspberry Pi DAC Pro HAT"
    ;;
  4)
    EEPFILE=rpi-digiampplus.eep
    OVERLAY=rpi-digiampplus
    BOARD="Raspberry Pi DigiAMP+ HAT"
    ;;
  *)
    exit 255
    ;;
esac

if flash_loop; then
  msgbox "Successfully programmed the $BOARD."
else
  fail "Failed to program the $BOARD."
fi

dtoverlay "$OVERLAY"
exit 0
