#!/bin/bash

OPKG_CMD_PREFIX="opkg install --force-depends ./provisioning/"
# On remove application do not force removal of opkg dependencies in case they include
# system libraries
# OPKG_CMD_PREFIX_R="opkg remove --force-depends "
OPKG_CMD_PREFIX_R="opkg remove"
MANIFEST="./provisioning/p_manifest.json"
NAME="Install"

bstnTar="DL"
bstnVer="03_03_22"
corpName="netmoregroup"
sDir="/var/config/app/NetmoreAgent"
bstnHome="/var/persistent/NetmoreAgent"
bstnLink="/opt/bstn"

# mPower API configuration
mPwrCfg=${bstnHome}/bstn/bin/bstn_mpower.py3
mPwrLog=${bstnHome}/bstn/var/log/mpower_install.log
mPwrPython="python3"
# if python3 is not available, fallback to python
if [ $(which python3 |wc -l) -eq 0 ] ; then
  mPwrPython="python"
  mPwrCfg=${bstnHome}/bstn/bin/bstn_mpower.py
fi

function install_bstn {
  isNew=1

  if [ -f ${bstnHome}/bstn/bin/bstnStatus.sh ] || \
     [ -f ${bstnLink}/bin/bstnStatus.sh ] ; then
    isNew=0
  fi

  installOK=0
  cVer=$(cat /etc/issue |grep "Version:" |awk '{print $2}')
  cVerDec=$(echo $cVer |sed 's/0*//;s/\./ /g' |awk '{printf "%d%02d%02d\n", $1,$2,$3}')
  prodId="unknown"
  if [ "$cVerDec" -eq "$cVerDec" ] 2>/dev/null ; then
    logger -t Install "NetmoreAgent Installation begin $cVer ($cVerDec)"
    # platform check
    prodId=$(mts-io-sysfs show product-id)
    prodPrefix=$(echo $prodId |sed 's/\-/ /' |awk '{print $1}')
    prodSuffix=$(echo $prodId |sed 's/\-/ /g' |awk '{print $NF}')
    prodSuffixNo=$(echo $prodSuffix |sed 's/[^0-9]//g')
    if [ "$prodPrefix" = "MTCDT" ] || [ "$prodPrefix" = "MTCDTIP" ] ; then
      case $prodSuffixNo in
        210 |220 |246 |247 |256 |266 |267)
          installOK=1
        ;;
      esac
    elif [ "$prodPrefix" = "MTCAP" ]  || \
         [ "$prodPrefix" = "MTCAP2" ] || \
         [ "$prodPrefix" = "MTCAP3" ] || \
         [ "$prodPrefix" = "MTCDTIP2" ] ; then
      installOK=1
    fi
  fi

  if [ $installOK -eq 0 ] ; then
    logger -t Install "NetmoreAgent Installation failed $cVer ($prodId)"
    if [ -d $sDir ] ; then
      sFile="${sDir}/status.json"
      printf "{\n  \"pid\": 0,\n  \"AppInfo\": \"Application not compatible with mPower $cVer ($prodId)\"\n}\n" > $sFile
      sync
    fi
    exit 99
  fi

  cNAME=$(echo $corpName |tr '[:lower:]' '[:upper:]')
  mtacSpi=0
  mtacId=$(mts-io-sysfs show lora/product-id)
  mtacHwVer=$(mts-io-sysfs show lora/hw-version)
  if [ $(echo ${mtacId} |grep -c "MTAC-LORA") -ge 1 ] || \
     [ $(echo ${mtacId} |grep -c "MTCAP-LORA") -ge 1 ] ; then
    mtacSpi=1
    if [ "$mtacHwVer" = "MTAC-LORA-1.0" ] ; then
      if [ $(echo $mtacId |grep "MTAC-LORA" |grep -c "SPI") -eq 0 ] ; then
        mtacSpi=0
      fi
    fi
    if [ "$bstnTar" = "DL" ] ; then
      if [ $cVerDec -ge 60300 ] && [ $cVerDec -lt 60400 ] ; then
        bstnTar="${cNAME}_Conduit_IP67v63.${bstnVer}.tgz"
      elif [ $cVerDec -ge 60000 ] && [ $cVerDec -lt 60300 ] ; then
        bstnTar="${cNAME}_Conduit_IP67v6.${bstnVer}.tgz"
      fi
    fi
  elif [ $(echo ${mtacId} |grep -c "MTAC-003") -ge 1 ] ; then
    mtacSpi=1
    if [ "$bstnTar" = "DL" ] ; then
      if [ $cVerDec -ge 60300 ] && [ $cVerDec -lt 60400 ] ; then
        bstnTar="${cNAME}_Conduit_1302_v63.${bstnVer}.tgz"
      elif [ $cVerDec -ge 60000 ] && [ $cVerDec -lt 60300 ] ; then
        bstnTar="${cNAME}_Conduit_1302_v6.${bstnVer}.tgz"
      fi
    fi
  elif [ $(echo "${mtacId}" |grep -c "MTCAP3-") -ge 1 ] ;then
    mtacSpi=1
    if [ "$bstnTar" = "DL" ] ; then
      if [ $cVerDec -ge 60300 ] && [ $cVerDec -lt 60400 ] ; then
        bstnTar="${cNAME}_Conduit_AP_300.${bstnVer}.tgz"
      elif [ $cVerDec -ge 70100 ] && [ $cVerDec -le 70300 ] ; then
        bstnTar="${cNAME}_Conduit_AP_300_v72.${bstnVer}.tgz"
      fi 
    fi
  fi

  # if bstnTar is still DL, then no suitable package found
  if [ "$bstnTar" = "DL" ] ; then
    logger -t Install "NetmoreAgent $cVer ($prodId) No available package"
    exit 98
  fi

  if [ $mtacSpi -eq 0 ] ; then
    logger -t Install "NetmoreAgent Installation failed $cVer ($prodId) mtac($mtacId:$mtacHwVer)"
    if [ -d $sDir ] ; then
      sFile="${sDir}/status.json"
      printf "{\n  \"pid\": 0,\n  \"AppInfo\": \"Application not compatible with MTAC ($mtacId:$mtacHwVer)\"\n}\n" > $sFile
      sync
    fi
    exit 99
  fi

  # Make any previous install symbolic
  if [ -d $bstnLink ] ; then
    if [ ! -L $bstnLink ] ; then
      mkdir -p $bstnHome
      mv /opt/bstn $bstnHome/.
      result=$?
      if [ $result != 0 ] ; then
        echo "Failed to move bstn files: $result"
        exit $result
      fi
      ln -s ${bstnHome}/bstn /opt/bstn 
    fi
  else
    ln -s ${bstnHome}/bstn $bstnLink
    sync
  fi

  # Preserve Files
  preserveFileList="bstn_cfg.json bstn_cfg_opt.json"
  for pfName in $preserveFileList ; do
    fName="${bstnHome}/bstn/etc/$pfName"
    if [ -f $fName ] && [ -d $sDir ] ; then
      cp -fp $fName ${sDir}/$pfName
    fi
  done

  # Download binary if not included in package
  if [ ! -f $bstnTar ] ; then
    logger -t Install "NetmoreAgent $cVer ($prodId) Attempting Download: $bstnTar"
    if [ "$corpName" = "netmoregroup" ] ; then
      dlLoc="https://docs.${corpName}.com/downloads/${bstnVer}/${bstnTar}"
    else
      dlLoc="https://docs.${corpName}.io/downloads/${bstnVer}/${bstnTar}"
    fi
    result=$(curl -s --fail -o ${bstnTar}.md5 ${dlLoc}.md5)
    stat=$?
    if [ $stat -ne 0 ] || [ ! -f ${bstnTar}.md5 ] ; then
      logger -t Install "NetmoreAgent Installation failed downloading ${dlLoc}.md5"
      echo "Failed to download ${bstnTar}.md5"
      exit $stat
    fi
    result=$(curl -s --fail -o ${bstnTar} ${dlLoc})
    stat=$?
    if [ $stat -ne 0 ] || [ ! -f ${bstnTar} ] ; then
      logger -t Install "NetmoreAgent Failed to download ${dlLoc} (${bstnTar})"
      echo "Failed to download ${bstnTar}"
      exit $stat
    fi
    if [ "$(md5sum "${bstnTar}" |awk '{print $1}')" != "$(cat ${bstnTar}.md5 |awk '{print $1}')" ] ; then
      logger -t Install "NetmoreAgent Failed to download ${bstnTar}, MD5 mismatch"
      echo "Failed to download ${bstnTar}, MD5 mismatch"
      exit 99
    fi
    logger -t Install "NetmoreAgent $cVer ($prodId) Downloaded: $bstnTar"
  fi

  # Extract basestation files
  pktFwdName="SenetPktFwd"
  if [ "$corpName" = "netmoregroup" ] ; then
    pktFwdName="NetmoreAgent"
  fi
  if [ ! -f $bstnTar ] ; then
    if [ -f ${sDir}/${pktFwdName}.tgz ] ; then
      tar -C $sDir -xzf ${pktFwdName}.tgz --no-same-owner
      result=$?
      if [ $result != 0 ] ; then
        logger -t Install "NetmoreAgent untar failed"
        echo "Untar ${pktFwdName} files failed: $result"
        exit $result
      fi
    fi
  fi
  mkdir -p $bstnHome
  tar -C $bstnHome -xzf $bstnTar --no-same-owner
  result=$?
  if [ $result != 0 ]; then
    logger -t Install "NetmoreAgent untar bstn failed"
    echo "Untar bstn files failed: $result"
    exit $result
  fi
  cp bstnStatus.sh ${bstnHome}/bstn/bin/.
  chmod +x ${bstnHome}/bstn/bin/bstnStatus.sh
  cp bstnStatusCtl.sh ${bstnHome}/bstn/bin/.
  chmod +x ${bstnHome}/bstn/bin/bstnStatusCtl.sh

  # Restore Files
  for pfName in $preserveFileList ; do
    fName="${sDir}/$pfName"
    if [ -f $fName ] && [ -d ${bstnHome}/bstn/etc ] ; then
      mv -f $fName ${bstnHome}/bstn/etc/$pfName
    fi
  done

  if [ $isNew -eq 1 ] ; then
    if [ -f $mPwrCfg ] ; then
      if [ ! -d /var/run/bstn ] ; then
        mkdir -p /var/run/bstn
      fi

      mkdir -p ${bstnHome}/bstn/var/log
      chmod +x $mPwrCfg
      $mPwrPython $mPwrCfg -v --logfile ${mPwrLog} profile DEVLITE
      profileStatus=$?
      if [ $profileStatus -ne 0 ] ; then
        logger -t Install "DEVLITE profile configuration failed with status $profileStatus"
        echo "DEVLITE profile configuration failed with status $profileStatus"
      fi
      
      # Enable SNTP, poll every 10 minutes
      $mPwrPython $mPwrCfg -v --logfile ${mPwrLog} sntp --enabled true --pollingTime 10
      sntpStatus=$?
      if [ $sntpStatus -ne 0 ] ; then
        logger -t Install "SNTP configuration failed with status $sntpStatus"
        echo "SNTP configuration failed with status $sntpStatus"
      fi
      # Add 2 extra pool servers 
      $mPwrPython $mPwrCfg -v --logfile ${mPwrLog} sntp --add-server 0.pool.ntp.org --add-server 1.pool.ntp.org
      sntpServerStatus=$?
      if [ $sntpServerStatus -ne 0 ] ; then
        logger -t Install "SNTP server configuration failed with status $sntpServerStatus"
        echo "SNTP server configuration failed with status $sntpServerStatus"
      fi
    else
      logger -t Install "$mPwrCfg not found, cannot configure DEV/LITE profile"
      echo "$mPwrCfg not found, cannot configure DEV/LITE profile"
    fi

    homeDir="/home/root"
    if [ ! -f ${homeDir}/.ssh/authorized_keys ] ; then
      mkdir -p ${homeDir}/.ssh
      touch ${homeDir}/.ssh/authorized_keys
    fi

    chmod 600 ${homeDir}/.ssh/authorized_keys
  fi

  # Cleanup
  sync
  rm $bstnTar
  rm $bstnTar.md5
}

#
# This function is called via the install argument.  It is invoked by the
# app-manager process during the install of a custom app.  It reads the
# p_manifest.json file in the provisioning directory of the application,
# and executes an "opkg install" on each package file listed in the p_manifest.
#
function install_packages {
    if [ ! -f "$MANIFEST" ]; then
        return
    fi
    JSONTXT=$(<./provisioning/p_manifest.json)
    PKGCNT=$(echo $JSONTXT | jsparser --count -p /pkgs)

    RETURNCODE=$?
    if [ $RETURNCODE -ne 0 ]; then
      echo "Failed to parse p_manifest.json as json"
      exit $RETURNCODE
    fi

    # Conduit 5.2.1 firmware mounts the /tmp folder with noexec option, so 
    # opkg cannot execute package preinst scripts. The fix is to remount
    # the /var/volatile mount point (where /tmp points) with exec option
    mount -o rw,exec,remount /var/volatile

    for ((i=0; i < PKGCNT; i++))
    do
        PKG=$(echo $JSONTXT | jsparser --jsobj -p /pkgs/$i)
        PKGNM=$(echo $PKG | jsparser -p /FileName)
        PKGTYPE=$(echo $PKG | jsparser -p /type)

        if [ "$PKGTYPE" == "ipk" ]; then
            PKGCMD=$OPKG_CMD_PREFIX$PKGNM
            echo "Executing: $PKGCMD"
            eval $PKGCMD
            if [ $? != 0 ]; then
                echo "Command [$PKGCMD] failed with status $?"
                logger -t Install "Command [$PKGCMD] failed with status $?"
                exit $?
            fi
        fi
        logger -t Install "Command [$PKGCMD] succeeded"
    done
}

#
# The Install script is invoked with the postinstall argument by the app-manager
# process after it has install an application succesfully and before it tries
# to start the app.  One example of something that might be done by this
# function would be to reboot the Conduit after the install if necessary.
#
function post_install {
    :
}

#
# This function is called via the remove argument.  It is invoked by app-manager
# during the uninstall of a custom app.  It reads the p_manifest.json file in
# the provisioning direcgtory of the application and executes an "opkg remove"
# on each package listed in the p_manifest.json.
#
function remove_packages {
    if [ ! -f "$MANIFEST" ]; then
        echo "provisioning manifest file not found"
        return
    fi
    JSONTXT=$(<./provisioning/p_manifest.json)
    PKGCNT=$(echo $JSONTXT | jsparser --count -p /pkgs)

    RETURNCODE=$?
    if [ $RETURNCODE -ne 0 ]; then
      echo "Failed to parse p_manifest.json as json"
      exit $RETURNCODE
    fi

    for ((i=0; i < PKGCNT; i++))
    do
        PKG=$(echo $JSONTXT | jsparser --jsobj -p /pkgs/$i)
        PKGNM=$(echo $PKG | jsparser -p /PkgName)
        PKGTYPE=$(echo $PKG | jsparser -p /type)

        if [ "$PKGTYPE" == "ipk" ]; then
            PKGCMD=$OPKG_CMD_PREFIX_R$PKGNM
            echo "Executing: $PKGCMD"
            eval $PKGCMD
            if [ $? != 0 ]; then
                echo "Command [$PKGCMD] failed with status $?"
                logger -t Install "Command [$PKGCMD] failed with status $?"
                exit $?
            fi
        fi
        logger -t Install "Command [$PKGCMD] succeeded"
    done

    $mPwrPython $mPwrCfg -v --logfile ${mPwrLog} profile DEVLITE

    ssLoc="${sDir}/Start"
    if [ -f $ssLoc ] ; then
      $ssLoc stop
    fi

    rm -rf ${bstnHome}/bstn
    rm -rf $bstnLink
    rm -rf /var/run/bstn
}

#
# The Install script is invoked with the postremove argument by the app-manager
# process after it has removed an application succesfully. One example of 
# something that might be done by this function would be to reboot the Conduit 
# after the remove if necessary.
#
function post_remove {
    echo "post_remove"
}

case "$1" in
  install)
      echo -n "Installing dependencies: "
      logger -t Install "Installing Dependencies: "
      install_packages
      install_bstn
      echo "$NAME."
      ;;
  remove)
      echo -n "Removing Dependencies: "
      logger -t Install "Removing Dependencies: "
      remove_packages
      echo "$NAME."
      ;;
  postinstall)
      echo -n "Running app post install "
      logger -t Install "Running app post install "
      post_install
      echo "$NAME."
      ;;
  postremove)
      echo -n "Running app post remove "
      logger -t Install "Running app post remove "
      post_remove
      echo "$NAME."
      ;;
  *)
      N=$NAME
      echo "Usage: $N {install|remove}" >&2
      exit 1
      ;;
esac

exit 0
