#!/bin/sh
#
# MEMI Helper application
#

LOG() {
  #printf "$1\n"
  local FAC=${3:-user}
  local LEV=${2:-info}
  logger -t memictl -p $FAC.$LEV "$1"
}

doInit() {

    # 30s max wait
    local MAXWAIT=$((30 * 5)) 
    local WAITELABSED=0

    LOG "Initialize MEMI environment ..."
    local EMIBASEDIR="/mnt/.mmc-storage"
    local XVAOS=$EMIBASEDIR/app
    local XVAOSBIN=$XVAOS/bin
    local XVAOSRES=$XVAOS/ressources
    local SYSETC=$EMIBASEDIR/etc
    local USERDATA=$EMIBASEDIR/data

    # Check and set hostname if not yet a 'VIBES-1xxxxxxxx' hostname
    doSetHostname
    
    # check for MEMI resource become available
    while [ ! -e $EMIBASEDIR/etc/emi/xvaos_version ]; 
    do
        if ! [ mountpoint -q "$EMIBASEDIR" ]; then
            mount -a
        fi

        sleep 0.2
        WAITELABSED=$((WAITELABSED+1))
        if [ $WAITELABSED -gt $MAXWAIT ]; then
            LOG "$0: [ERROR] Wait for MEMI storage become available timed out ..."
            exit 2
        fi        
    done

    # create symbolic link for binary files
    if [ ! -L "/usr/bin/emi" ] && [ -d $XVAOSBIN ]; then
        LOG "$0 create symlink /usr/bin/emi ->  $XVAOSBIN"
        doRootFsRw
        rm -r "/usr/bin/emi"
        ln -s $XVAOSBIN "/usr/bin/emi"
        doRootFsRo
    else
        LOG "$0 /usr/bin/emi already a linked or '$XVAOSBIN' does not exist, skipped"    
    fi

    # create symbolic link for shared resources
    if [ ! -L "/usr/share/emi" ] && [ -d $XVAOSRES ]; then
        LOG "$0 create symlink /usr/share/emi ->  $XVAOSRES"
        doRootFsRw
        rm -r "/usr/share/emi"
        ln -s $XVAOSRES "/usr/share/emi"
        doRootFsRo
    else
        LOG "$0 /usr/share/emi already a linked or '$XVAOSRES' does not exist, skipped"    
    fi

    # create symbolic link for xvaos user data
    if [ ! -e "/var/lib/emi" ] && [ -d $USERDATA/emi ]; then
        LOG "$0 create symlink /var/lib/emi ->  $USERDATA/emi"
        doRootFsRw
        rm -r "/var/lib/emi"
        ln -s $USERDATA/emi "/var/lib/emi"
        doRootFsRw
    else
        LOG "$0 /var/lib/emi already a linked or '$USERDATA/emi' does not exist, skipped"    
    fi

    # overlay over /etc
    if [ -d "/etc" ]  && [ -d $SYSETC ]; then
        if ! mountpoint -q "/etc" ; then
            if [ ! -d "$USERDATA/.etcovwork" ]; then
                mkdir -p "$USERDATA/.etcovwork"
            fi
            mount -t overlay -o lowerdir=/etc,upperdir=$SYSETC,workdir=$USERDATA/.etcovwork overlay /etc
        else
            LOG "$0 /etc is already a mountpoint, skipped"    
        fi
    else
        LOG "$0 failed to create overlay /etc"
    fi

    # Make root filesystem read only
    doRootFsRo

    # bring up can0
    local CANSTAT=$(cat /sys/class/net/can0/operstate)
    if [ ! "$CANSTAT" == "up" ]; then
      ifup can0
    else
      LOG "can0 already up ..."
    fi

    # set processor speed
    LOG "Set CPU speed to 1400000"
    echo "1400000" > "/sys/devices/system/cpu/cpu0/cpufreq/scaling_setspeed"

    # enable mdev hotplug
    local CMDEV=$(cat /proc/sys/kernel/hotplug)
    if [ -z CMDEV ]; then
      LOG "Enable mdev hotplug"
      echo >/dev/mdev.seq
      echo /sbin/mdev >/proc/sys/kernel/hotplug
      mdev -s
    else
      LOG "/proc/sys/kernel/hotplug already set to $CMDEV"
    fi 
}

doInitStartApps() {

    # Workaround to make I2C work
    LOG "Reload kernel module i2c_bcm2835"    
    rmmod i2c_bcm2835
    modprobe i2c_bcm2835

    # Hack fix do get midi devices work on startup
    LOG "Wait (2s) for MIDI devices ..."
    sleep 2    
    LOG "Wait (2s) for MIDI devices ... done"

    # restart syntehsizer
    doStopMemiApps
    doStartMemiApps

}

doStartMemiApps() {
    local APPNAME=${1:-*}

    for i in /etc/emi/app.d/${APPNAME}.enabled ; do

	LOG "Start service '$i'"
        if [ ! -e $i ]; then
            LOG "'$i' does not exist"
        fi

        # Ignore dangling symlinks (if any).
        [ ! -e "$i" ] && continue
	    (
		trap - INT QUIT TSTP
		set start
		. $i
	    )
    done
}

doStopMemiApps() {
    local APPNAME=${1:-*}

    for i in /etc/emi/app.d/${APPNAME}.enabled ; do

	LOG "Stop service '$i'"
        if [ ! -e $i ]; then
            LOG "'$i' does not exist"
        fi

        # Ignore dangling symlinks (if any).
        [ ! -e "$i" ] && continue
	    (
		trap - INT QUIT TSTP
		set stop
		. $i
	    )     
    done
}

doEnableMemiApps() {

    if ! [ "$1" == "" ]; then
        if [ -e /etc/emi/app.d/${1}.disabled ]; then
          mv /etc/emi/app.d/${1}.disabled /etc/emi/app.d/${1}.enabled
          LOG "'/etc/emi/app.d/${1}.disabled' enabled"
        else
	    if [ -e /etc/emi/app.d/${1}.enabled ]; then
                LOG "'/etc/emi/app.d/${1}' already enabled"
            else
                LOG "'/etc/emi/app.d/${1}.disabled' does not exist"
            fi
        fi
    else
      doShowUsage
    fi
}

doDisableMemiApps() {

    if ! [ "$1" == "" ]; then
        if [ -e /etc/emi/app.d/${1}.enabled ]; then
            doStopMemiApps ${1}
            mv /etc/emi/app.d/${1}.enabled /etc/emi/app.d/${1}.disabled
            LOG "'/etc/emi/app.d/${1}.disabled' disabled"
        else
            if [ -e /etc/emi/app.d/${1}.disabled ]; then
                LOG "'/etc/emi/app.d/${1}' already disabled"
            else
                LOG "'/etc/emi/app.d/${1}.enabled' does not exist"
            fi
        fi
    else
        doShowUsage
    fi
}

doRegisterMemiApps() {
    local SERVICEPATH=$1
    local BASENAME=$(basename $SERVICEPATH)
    local APPNAME=${2:-${BASENAME%.*}}
	
    if ! [ "$1" == "" ]; then
        ln -s $1 /etc/emi/app.d/${APPNAME}.enabled
        LOG "'$1' registered as ${APPNAME}.enabled"
    fi
}

doUnregisterMemiApps() {

    if ! [ "$1" == "" ]; then
        if [ -e /etc/emi/app.d/${1}.enabled ]; then
            doStopMemiApps ${1}
            rm /etc/emi/app.d/${1}.enabled
            LOG "'${1}.enabled' removed"
        else
            if [ -e /etc/emi/app.d/${1}.disabled ]; then
                rm /etc/emi/app.d/${1}.disabled
                LOG "'${1}.disabled' removed"
            else
                LOG "Service '${1}' not found"
            fi
        fi
    fi
	
}

doSetHostname() {
    CHN=$(hostname)

    HN=$(cat /sys/firmware/devicetree/base/serial-number | sed -r 's/0000000//g')
    HN=VIBES-$HN

    #if ! [[ $CHN == VIBES-1* ]]; then
    if ! [[ $CHN == $HN ]]; then
        LOG "$CHB hostname does not reflect current device serial, set to $HN"
        echo $HN > /etc/hostname
        hostname -F /etc/hostname
    fi
}

doRootFsRo() {
    mount -o remount,ro /
}

doRootFsRw() {
    mount -o remount,rw /
}

doSplashScreen() {

    if [ "$1" == "-b" ]; then
      xzcat /etc/emi/msplash-boot.dat.xz > /dev/fb0
    else
      xzcat /etc/emi/msplash.dat.xz > /dev/fb0
    fi
}

doMountBoot() {
   mkdir -p /tmp/boot && mount /dev/mmcblk0p1 /tmp/boot
   cd /tmp/boot
}

doRebootAdmin() {

  doMountBoot

  if [ -e /tmp/boot/config.txt-a ]; then
      if [ -e /tmp/boot/mprod ]; then
        rm /tmp/boot/mprod
      fi
      touch /tmp/boot/madmin
      mv /tmp/boot/config.txt /tmp/boot/config.txt-p
      mv /tmp/boot/config.txt-a /tmp/boot/config.txt
      reboot
  else
    LOG "Administration Mode config file not found, not booting"
  fi
}

doShowUsage() {
  echo $"Usage: $0"
  echo $"  {init|start|stop}                     MEMI System initialization"
  echo $"  initapps                              All services initial startup"
  echo $"  {start|stop|enable|disable} <name>    Start|Stop|enable|disable <name> service"
  echo $"  register <path> [<name>]              Register a service file with <name>"
  echo $"                                        Name derived from path filename if omitted"
  echo $"  unregister <name>                     Unregister a service of given name"
}

case "$1" in
  init)
    doInit
    ;;
  initapps)
    doInitStartApps
    ;;
  start)
    doStopMemiApps $2
    doStartMemiApps $2
    ;;
  stop)
    doStopMemiApps $2
    ;;
  enable)
	doEnableMemiApps $2
	;;
  disable)
    doDisableMemiApps $2
	;;
  register)
    doRegisterMemiApps $2 $3
	;;
  unregister)
    doUnregisterMemiApps $2
	;;
  rootrw)
    doRootFsRw
    ;;
  rootro)
    doRootFsRo
    ;;
  showsplash)
    doSplashScreen $2
    ;;
  mboot)
    doMountBoot
    ;;
  rebootadmin)
    doRebootAdmin
    ;;
  *)
	doShowUsage
    exit 1
esac

