#!/bin/bash
#
# This is an sdm plugin for: serial
#
# The plugin is called three times: for Phase 0, Phase 1, and post-install.
#
# Notes from Forum:
#
# Pi 5 is different because it has the Debug connector, which is more convenient as it allows the UART to be used even when a HAT is fitted.
# However, to enable UART0 on GPIOs 14 and 15 and make it /dev/serial0:
#   dtparam=uart0_console=on
#   Be aware that bootloader output is only presented on the Debug connector.
#
function loadparams() {
    source $SDMPT/etc/sdm/sdm-readparams
}

#
# From /bin/raspi-config
#
function set_config_var() {
  lua - "$1" "$2" "$3" <<EOF > "$3.bak"
local key=assert(arg[1])
local value=assert(arg[2])
local fn=assert(arg[3])
local file=assert(io.open(fn))
local made_change=false
for line in file:lines() do
  if line:match("^#?%s*"..key.."=.*$") then
    line=key.."="..value
    made_change=true
  end
  print(line)
end

if not made_change then
  print(key.."="..value)
end
EOF
mv "$3.bak" "$3"
}

function do_serial_cons() {
    # $1: y:enable serial console <anything else>:disable
    local efl=$1

    if [ "$efl" == "y" ]
    then
	logtoboth "> Plugin $pfx: Enable shell on console serial port"
	if grep -q "console=ttyAMA0" $cmdline
	then
	    if [ -e /proc/device-tree/aliases/serial0 ]
	    then
		sed -i $cmdline -e "s/console=ttyAMA0/console=serial0/"
	    fi
	elif ! grep -q "console=ttyAMA0" $cmdline && ! grep -q "console=serial0" $cmdline
	then
	    if [ -e /proc/device-tree/aliases/serial0 ]
	    then
		sed -i $cmdline -e "s/root=/console=serial0,115200 root=/"
	    else
		sed -i $cmdline -e "s/root=/console=ttyAMA0,115200 root=/"
	    fi
	fi
    else
	logtoboth "> Plugin $pfx: Disable shell on console serial port"
	sed -i $cmdline -e "s/console=ttyAMA0,[0-9]\+ //"
	sed -i $cmdline -e "s/console=serial0,[0-9]\+ //"
    fi
}

function do_serial_hw() {
    if [ "$enableuart" == "y" ]
    then
	if [ "$pi5" == "y" ]
	then
	    if [ "$pi5debug" != "y" ]
	    then
		logtoboth "> Plugin $pfx: Enable Pi5 uart0 console serial port"
		set_config_var dtparam=uart0_console on $configtxt
	    else
		logtoboth "> Plugin $pfx: Enable Pi5 debug console serial port"
		set_config_var dtparam=uart0 on $configtxt
	    fi
	else
	    logtoboth "> Plugin $pfx: Enable non-Pi5 console serial port"
	    set_config_var enable_uart 1 $configtxt
	fi
    else
	logtoboth "> Plugin $pfx: Disable console serial port"
	sed -i $cmdline -e "s/console=ttyAMA0,[0-9]\+ //"
	sed -i $cmdline -e "s/console=serial0,[0-9]\+ //"
	if [ "$pi5" == "y" ]
	then
            sed $configtxt -i -e "/dtparam=uart0.*/d"
	else
	    set_config_var enable_uart 0 $configtxt
	fi
	return
    fi
}

function converty() {
    [ -v pi5 ]   && pi5=y
    [ -v enableshell ] && enableshell=y
    [ -v disableshell ] && disableshell=y
    [ -v enableuart ] && enableuart=y
    [ "$disableshell" == "y" ] && enableshell="" # In case uart enabled with no shell desired && enableuart=""
    [ "$enableshell" == "y" ] && enableuart=y
    [[ "$enableshell" != "y" ]] && [[ "$disableshell" != "y" ]] && disableshell=y
    [ -v pi5debug ] && { pi5=y ; pi5debug=y ; }
}

# $1 is the phase: "0", "1", or "post-install"
# $2 is the argument list: arg1=val1|arg2=val2|arg3=val3| ...
#
# Main code for the Plugin
#
phase=$1
pfx="$(basename $0)"     #For messages
args="$2"
loadparams
vldargs="|pi5|disableshell|enableshell|enableuart|pi5debug|"     #"|list|of|valid|args|"
rqdargs=""                   # |list|of|required|args|or|nullstring|
assetdir="$SDMPT/etc/sdm/assets/$pfx"
cmdline="/boot/firmware/cmdline.txt"
configtxt="/boot/firmware/config.txt"
if [ ! -d /boot/firmware ]
then
    cmdline="/boot/cmdline.txt"
    configtxt="/boot/config.txt"
fi

if [ "$phase" == "0" ]
then
    #
    # In Phase 0 all references to directories in the image must be preceded by $SDMPT
    #
    logtoboth "* Plugin $pfx: Start Phase 0"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs" || exit
    #mkdir -p $assetdir
    logtoboth "* Plugin $pfx: Complete Phase 0"
elif [ "$phase" == "1" ]
then
    #
    # Phase 1 (in nspawn)
    #
    logtoboth "* Plugin $pfx: Start Phase 1"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs"
    converty
    do_serial_hw
    do_serial_cons $enableshell
    logtoboth "* Plugin $pfx: Complete Phase 1"
elif [ "$phase" == "post-install" ]
then
    #
    # Plugin Post-install edits
    #
    logtoboth "* Plugin $pfx: Start Phase post-install"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs"
    logtoboth "* Plugin $pfx: Complete Phase post-install"
fi
