#!/sbin/sh
## Kali NetHunter kernel installer
##
## Detect bootmode
##   BOOTMODE=true  = Device has booted into system (NetHunter installed as Magisk module)
##   BOOTMODE=false = Device has booted into recovery (NetHunter installed through TWRP)

#set -e
#set -x

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

# Magisk - echo     (really, any output on stdout, not stderr)
# TWRP   - ui_print (If not prefix with ui_print, will not work - multilines may not work)
print() {
  if $BOOTMODE; then
    echo "${1}"
  else
    echo "${1:- }" \
      | while IFS='' read -r line; do
         echo -e "ui_print $1\nui_print" >> $console
      done
  fi
}

debug() {
  [ -n "$DEBUG" ] && print "@ $1"
}

# extract <ZIP FILE> <OUT DIR> [<SKIP>]
extract() {
  rm -rf "$2"
  mkdir -p "$2"
  unzip -qq -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
}

# extract_file <ZIP FILE> <FILE TO EXTRACT> <OUT DIR>
extract_file() {
  rm -rf "$3"
  mkdir -p "$3"
  unzip -qq -o "$1" "$2" -d "$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" {} \;
}

#<REF: ./scripts/util_functions.sh>
[ -z $BOOTMODE ] && ps | grep zygote | grep -qv grep && BOOTMODE=true
[ -z $BOOTMODE ] && ps -A 2>/dev/null | grep zygote | grep -qv grep && BOOTMODE=true
[ -z $BOOTMODE ] && BOOTMODE=false
#</REF: ./scripts/util_functions.sh>

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

DEBUG=${DEBUG:-}
TMPDIR=/dev/tmp
export TMP=$TMPDIR/nethunter # Doesn't matter if sh / source

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

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 ""
if $BOOTMODE; then
print "* NetHunter Kernel (Magisk)"        # Skipping indent formatting
else
print "* NetHunter Kernel (Recovery/TWRP)" # Skipping indent formatting
fi
debug "Debug Mode: Enabled"
print ""

mount /data || true # May fail, if we don't have /etc/fstab

if $BOOTMODE; then
  #####################################################
  ## Install in Magisk                               ##
  ##   ./scripts/util_functions.sh: install_module() ##
  #####################################################
  set_perm() {
    chown $2:$3 $1 || return 1
    chmod $4 $1 || return 1
    CON=$5
    [ -z $CON ] && CON=u:object_r:system_file:s0
    chcon $CON $1 || return 1
  }

  set_perm_recursive() {
    find $1 -type d 2>/dev/null | while read dir; do
      set_perm $dir $2 $3 $4 $6
    done

    find $1 -type f -o -type l 2>/dev/null | while read file; do
      set_perm $file $2 $3 $5 $6
    done
  }

  require_new_magisk() {
    echo "*******************************"
    echo " Please install Magisk v20.4+! "
    echo "*******************************"
    exit 1
  }

  ## REF: ./scripts/module_installer.sh
  [ -f /data/adb/magisk/util_functions.sh ] || require_new_magisk
  source /data/adb/magisk/util_functions.sh || print "! Issue with util_functions.sh"
  [ $MAGISK_VER_CODE -lt 20400 ] && require_new_magisk

  umask 022

  ## Make setup_flashable() happy
  OUTFD=${OUTFD:- $2} # May already be defined ($ adb shell 'su -c magisk --install-module [...]')

  print "* Unpacking script"
  extract_file "$ZIPFILE" META-INF/com/google/android/update-magisk $TMP
  #print "* Script unpacked"

  ## Default permissions
  set_perm_recursive $TMP 0 0 0755 0644
  ## Run Magisk script (aka what would load customization script - ./customize.sh)
  [ -f $TMP/META-INF/com/google/android/update-magisk ] && source $TMP/META-INF/com/google/android/update-magisk    # Don't spawn a new session (aka using sh), do in current session (able to pass variables/functions)
else
  #####################################################
  ## Install in recovery/TWRP                        ##
  #####################################################
  print "* Unpacking ZIP"
  extract "$ZIPFILE" "$TMP"
  print "* Running boot-patcher script"
  [ -f $TMP/META-INF/com/google/android/update-binary-nethunter ] && source $TMP/META-INF/com/google/android/update-binary-nethunter   # Don't spawn a new session (aka using sh), do in current session (able to pass variables/functions)
fi

print ""
print "################################################"
print "#   Kali NetHunter kernel is now installed!    #"
print "################################################"
print ""
