#! /bin/sh
# Script for setting the correct USB controls settings in UCI when triggered by the WebUI
# or by plugging/unplugging the USB audio card
# Created by Alex Simeonov, 08.03.2024, Barix AG
#

# Get HW type in case we need to handle monitor output for LX-400
HW_TYPE=$(/usr/bin/qiba-spi-get-production-info.sh -w)
ARECORD_PID=$(/usr/bin/pgrep -f arecord)
LX_MONITOR_ON=0

# config files to check:
OLD_LOCAL_CONFIG=/etc/local_config.json
NEW_LOCAL_CONFIG=/barix/local/config/local_config.json

# internal audio cards have been modified by the webUI, check them
AUDIO_SETTINGS_CHANGED=0
NEW_AD_GAIN=$(/sbin/uci get -q instreamer.audio.ad_gain)
NEW_MONITOR_INPUT=$(/sbin/uci get -q instreamer.audio.monitor_input)
NEW_MONITOR_INPUT_GAIN=$(/sbin/uci get -q instreamer.audio.monitor_input_gain)
CURRENT_AD_GAIN=$(/usr/bin/amixer -c2 sget 'ADC Gain' | grep "Mono: Capture" | cut -d' ' -f7 | tr -d '[]' | tr -d 'dB')
CURRENT_MONITOR_INPUT_GAIN=$(/usr/bin/amixer -c2  sget "Line In" | grep "Front Left:" | cut -d' ' -f8 | tr -d '[]' | tr -d 'dB')
CURRENT_MONITOR_INPUT=$(/usr/bin/amixer -c2  sget "Line In" | grep "Front Left:" | cut -d' ' -f9 | tr -d '[]')
OLD_UCI_SETTINGS=/tmp/instreamer_uci.old
NEW_UCI_SETTINGS=/tmp/instreamer_uci.new

# USB Card specific control settings to check
USB_SETTINGS_CHANGED=0
USB_DETECT_SCRIPT=/etc/init.d/alsa-usb-detect
OLD_USB_SETTINGS=/tmp/usb_cards.old
NEW_USB_SETTINGS=/tmp/usb_cards.new

# Flag to restart the application
APP_SHOULD_RESTART=0

print_msg() {
	echo "instreamer: $@"
	logger "instreamer: $@"
}

start() {
	check_audio_settings
	check_for_usb_changes
	check_for_uci_changes
	restart_instreamer
	handle_lx400_monitor
}

stop() {
	:
}

restart() {
	stop
	start
}

check_for_usb_changes(){
  msg="Checking if USB card settings have changed..."
  print_msg $msg
  uci -q show usb_cards | grep -v 'section' > "$NEW_USB_SETTINGS"
	NEW_USB_MD5_SUM=$(cat "$NEW_USB_SETTINGS" | md5sum | cut -d' ' -f1)
	msg="New USB UCI MD5SUM: $NEW_USB_MD5_SUM"
	print_msg $msg

	if [ -f "$OLD_USB_SETTINGS" ]; then
		OLD_USB_MD5_SUM=$(cat "$OLD_USB_SETTINGS" | md5sum | cut -d' ' -f1)
		msg="Old USB UCI MD5SUM: $OLD_USB_MD5_SUM"
		print_msg $msg
		mv "$NEW_USB_SETTINGS" "$OLD_USB_SETTINGS"
		if [ "$OLD_USB_SETTINGS" != "$NEW_USB_MD5_SUM" ]; then
			USB_SETTINGS_CHANGED=1
		fi
	else
		# first run, just copy over the settings
		msg="First run, just storing the USB UCI settings hash ..."
		print_msg $msg
		mv "$NEW_USB_SETTINGS" "$OLD_USB_SETTINGS"
		#first run, consider USB settings as changed
		USB_SETTINGS_CHANGED=1
	fi
}

check_for_uci_changes(){
	# This function mimics the uci "deps" of run-flexa from the instreamer settings change
	# Changes in monitor_input, ad_gain, and monitor_input gain do not require application 
	# restart. All other parameters do require the application restart to take into effect
	msg="Checking if Multicoder UCI settings have changed..."
	print_msg $msg
	uci show instreamer | grep -v 'monitor_input\|ad_gain\|section\|usb_settings_changed' > "$NEW_UCI_SETTINGS"
	NEW_MD5_SUM=$(cat "$NEW_UCI_SETTINGS" | md5sum | cut -d' ' -f1)
	msg="New Multicoder UCI MD5SUM: $NEW_MD5_SUM"
	print_msg $msg

	if [ -f "$OLD_UCI_SETTINGS" ]; then
		OLD_MD5_SUM=$(cat "$OLD_UCI_SETTINGS" | md5sum | cut -d' ' -f1)
		msg="Old Multicoder UCI MD5SUM: $OLD_MD5_SUM"
		print_msg $msg
		mv "$NEW_UCI_SETTINGS" "$OLD_UCI_SETTINGS"
		if [ "$OLD_MD5_SUM" != "$NEW_MD5_SUM" ]; then
			APP_SHOULD_RESTART=1
		fi
	else
		# first run, just copy over the settings
		msg="First run, just storing the UCI settings hash ..."
		print_msg $msg
		mv "$NEW_UCI_SETTINGS" "$OLD_UCI_SETTINGS"
	fi
}

handle_lx400_monitor(){
# alsa-state service is recreating the ALSA plugins, so start LX-400 monitor here if needed
  if [ "$HW_TYPE" == "80" ]; then
	  if [ "$LX_MONITOR_ON" -gt 0 ]; then
	    # start the monitor feedback only if not yet already
	    if [ "X$ARECORD_PID" == "X" ]; then
	      msg="Starting the monitoring feedback on LX-400 ..."
	      print_msg $msg
	      arecord -D plug:linein_stereo -r 48000 -c 2 -f S16_LE | aplay &
	    else
	      msg="LX-400 monitoring feedback already active ..."
	      print_msg $msg
	    fi
	    # on LX-400 always set the the USB card volume to 100% when the feedback is enabled
	    # do not set it to 100% for now, let's use the PCM Playback volume as it is,
	    # and remove the Volume from application general settings
		  # /usr/bin/amixer -c3 -q -- sset 'PCM' "100"
	  else
	    # stopping the monitor feedback
	    msg="Stopping the LX-400 monitor feedback ..."
	    print_msg $msg
	    pkill -9 arecord
	  fi
  fi
}

restart_instreamer(){
  APP_STOPPED=0
  if [ "$APP_SHOULD_RESTART" -gt 0 ]; then
    msg="Multicoder UCI settings changed, restarting the application ..."
		print_msg $msg
    /etc/init.d/run-flexa stop
    APP_STOPPED=1
  fi

  # USB card controls could be applied  on the fly, without restarting the app
  # but if the app is already stopped, set them here
  if [ -f "$USB_DETECT_SCRIPT" ] && [ "$USB_SETTINGS_CHANGED" -gt 0 ]; then
    msg="Storing the new USB Card settings ..."
    print_msg $msg
    eval "$USB_DETECT_SCRIPT usb_store"
	fi

	# restart the app if we have stopped it
	if [ "$APP_SHOULD_RESTART" -gt 0 ] && [ "$APP_STOPPED" -gt 0 ]; then
	  msg="Restarting the Multicoder ..."
	  print_msg $msg
		/etc/init.d/run-flexa start
  fi
}

check_audio_settings() {
	msg="Checking if Multicoder audio settings have changed..."
	print_msg $msg

	if [ "X$NEW_AD_GAIN" != "X" ]; then
		if [ "$NEW_AD_GAIN" != "$CURRENT_AD_GAIN" ]; then
			msg="Setting new AD Gain: $NEW_AD_GAIN dB"
			print_msg $msg
			/usr/bin/amixer -c2 -q -- sset 'ADC Gain' "$NEW_AD_GAIN"dB
			AUDIO_SETTINGS_CHANGED=1
		fi
	fi
	
	if [ "X$NEW_MONITOR_INPUT" != "X" ]; then
	  msg="Setting new Monitor Enable to: $NEW_MONITOR_INPUT"
    print_msg $msg
    /usr/bin/amixer -c2 -q -- sset 'Line In' "$NEW_MONITOR_INPUT"

    if [ "$HW_TYPE" == "80" ]; then
      msg="LX-400 detected"
      print_msg $msg
      if [ "$NEW_MONITOR_INPUT" == "off" ]; then
        msg="Deactivating LX-400 output ..."
        print_msg $msg
        LX_MONITOR_ON=0
      else
        # start arecord if not running
        msg="Activating LX-400 monitor output ..."
        print_msg $msg
        LX_MONITOR_ON=1
      fi
    fi
		if [ "$NEW_MONITOR_INPUT" != "$CURRENT_MONITOR_INPUT" ]; then
			AUDIO_SETTINGS_CHANGED=1
		fi
	fi
	
	if [ "X$NEW_MONITOR_INPUT_GAIN" != "X" ]; then
		if [ "$NEW_MONITOR_INPUT_GAIN" != "$CURRENT_MONITOR_INPUT_GAIN" ]; then
			msg="Setting new Line In Gain: $NEW_MONITOR_INPUT_GAIN dB"
			print_msg $msg
			/usr/bin/amixer -c2 -q -- sset 'Line In' "$NEW_MONITOR_INPUT_GAIN"dB
			AUDIO_SETTINGS_CHANGED=1
		fi
	fi
	
	if [ "$AUDIO_SETTINGS_CHANGED" -gt 0 ]; then
	  msg="Multicoder audio settings changed, adjusting them runtime ..."
	  print_msg $msg
		/etc/init.d/alsa-state stop
		/etc/init.d/alsa-state start
	fi 
}

# See how we were called.
case "$1" in
	start)
		start
		;;
  force_start)
    APP_SHOULD_RESTART=1
		start
		;;
	stop)
		stop
		;;
	restart|reload)
		restart
		;;
	*)
	echo "Usage: $0 {start|stop|restart|force_start}"
	exit 1
esac

exit 0
