#!/sbin/sh
## Kali NetHunter boot image patcher (aka kernel installer)
##   This mostly does prep work, ready to call AnyKernel3

#set -x

#------------------------------------------------------------------------------

print() {
  echo "${1:- }" \
    | while read -r line; do
       echo -e "ui_print $line" > "$console"
       echo -e "ui_print \n" > "$console"
    done
}

abort() {
  [ "$1" ] && {
    print "! Error: $1"
    print "$prefix Aborting"
  }
  cleanup
  print "! Failed to patch boot image"
  exit 1
}

cleanup() {
  [ "$ZIPFILE" ] && {
   rm /tmp/console
  }
  cd $(dirname $TMP)
  rm -rf $TMP
}

install() {
  setperm "$2" "$3" "$TMP$1"
  if [ "$4" ]; then
    cp -r "$TMP$1" "$(dirname "$4")/"
    return
  fi
  cp -r "$TMP$1" "$(dirname "$1")/"
}

extract() {
  rm -rf "$2"
  mkdir -p "$2"
  unzip -o "$1" -d "$2" -x "$3" >&2 ||
    abort "Failed to extract! The zip may be corrupt or your device may not have enough RAM to proceed. Consider using a smaller installer if it is available" # Or ARM 32 device doing a too big ZIP file
}

setperm() {
  find "$3" -type d -exec chmod "$1" {} \;
  find "$3" -type f -exec chmod "$2" {} \;
}

get_bb() {
  cd $TMP/tools/
  BB_latest=$( (ls -v busybox_nh-* 2>/dev/null || ls busybox_nh-*) | tail -n 1)
  [ -z $BB_latest ] && abort "Failed to find a NetHunter's BusyBox: $TMP/tools/busybox_nh-*"
  BB=$TMP/tools/$BB_latest # Use NetHunter BusyBox from ./arch/<arch>/tools/
  chmod 0755 $BB # Make BusyBox executable
  echo $BB
  cd - >/dev/null
}

install_recovery_bb() {
  ## To identify the latest BusyBox version, we need the command "ls -v" which is not supported by all TWRP versions
  ##   We will pick the best available BusyBox version and use that to run "ls -v" to pick the latest version for the recovery partition
  cd $TMP/tools/

  ## Try to pick the latest version of BusyBox, if "ls -v" is not supported by the recovery then make an educated guess for a later version
  recovery_bb=$( (ls -v busybox_nh-* 2>/dev/null || ls busybox_nh-*) | tail -n 1 )
  [ -z $recovery_bb ] && abort "Failed to find a recovery BusyBox: $TMP/tools/busybox_nh-*"
  cp $recovery_bb busybox_tmp
  setperm 0755 0755 busybox_tmp

  ## Now that we picked a reasonably current BusyBox, use that to copy the absolute latest to the recovery partition using "ls -v"
  nethunter_bb=$(./busybox_tmp ls -v busybox_nh-* | tail -n 1)
  print "** Installing $nethunter_bb applets to /sbin"
  cp $nethunter_bb /sbin/busybox_nh
  /sbin/busybox_nh --install /sbin
  cd - >/dev/null
}

#------------------------------------------------------------------------------

if [ "$3" ]; then
  ZIPFILE=$3
  console=/proc/$$/fd/$2
  ## Write the location of the console buffer to /tmp/console for other scripts to use
  [ -d /tmp ] && echo "$console" > /tmp/console        # Magisk doesn't have /tmp
else
  [ -f /tmp/console ] && console=$(cat /tmp/console)   # Magisk doesn't have /tmp
  [ "$console" ] || console=/proc/$$/fd/1
fi

SYSTEM="/system"
TMPDIR=/dev/tmp
TMP=$TMPDIR/nethunter/boot-patcher # This is fixed path due to ./installer/, as that extracts and needs to know of this path
test "$ANDROID_ROOT" || ANDROID_ROOT="$SYSTEM" # Alt: [ "$ANDROID_ROOT" ] || ANDROID_ROOT=$SYSTEM

#------------------------------------------------------------------------------

## How has this script been called? (Sourced vs Standalone)
if [ "$ZIPFILE" ] && [ ! -d "$TMP" ]; then
  prefix="*"   # Being called direct (first script being ran)
  print ""
  print "################################################"
  print "#                                              #"
  print "#  88      a8P         db        88        88  #"
  print "#  88    .88'         d88b       88        88  #"
  print "#  88   88'          d8''8b      88        88  #"
  print "#  88 d88           d8'  '8b     88        88  #"
  print "#  8888'88.        d8YaaaaY8b    88        88  #"
  print "#  88P   Y8b      d8''''''''8b   88        88  #"
  print "#  88     '88.   d8'        '8b  88        88  #"
  print "#  88       Y8b d8'          '8b 888888888 88  #"
  print "#                                              #"
  print "###  ############# NetHunter ###################"
  print ""
  print "$prefix Boot-Patcher (A/B and A devices)"
  print ""
else
  prefix="-"   # Being called indirect
  print "################################################"
  print "#       Boot-Patcher (A/B and A devices)       #"
  print "################################################"
fi

## Unpack the ZIP
if [ "$ZIPFILE" ]; then
  ## Fresh start
  rm -rf "$TMP"
  mkdir -p "$TMP"

  print "$prefix Unpacking the ZIP, this may take a while"
  extract "$ZIPFILE" "$TMP"
  #print "$prefix ZIP unpacked"
elif [ ! -d "$TMP" ]; then
  ## Did installer fail to extract?
  abort "Missing ZIPFILE & $TMP"
fi

cd "$TMP"

print "$prefix Loading environment"
source "$TMP/env.sh"

print "$prefix Setting permissions"
setperm 0755 0755 tools

print "$prefix Setting up BusyBox"
BB=$(get_bb)
## Install BusyBox applets if they haven't been installed by nethunter already
[ -e $TMP/tools/busybox_tmp ] || install_recovery_bb

print "$prefix Running boot image patcher"
sh "META-INF/com/google/android/update-binary-anykernel" 2>&1 || abort "boot image patcher failed" # Spawn a new session (aka using sh), don't do it in the current session
#print "$prefix Boot image patcher done"

print "$prefix Boot image patching complete"
cleanup
