#!/system/bin/sh
# Terminal Magisk Mod Template
# by veez21 @ xda-developers
# Slimmed down for use as an app backend by @Skittles9823

# Magisk Module ID
ID="quickstepswitcher"

# Magisk Mod Directory
if [ -d /data/adb/modules_update/$ID ]; then
  MOUNTPATH="/data/adb/modules_update"
else
  MOUNTPATH="/data/adb/modules"
fi
MODDIR="$MOUNTPATH/$ID"
[ ! -d $MODDIR ] && { exit 1; }

cd $MODDIR

# Set Log Files
# > Logs should go in this file
mkdir -p $MODDIR/logs
LOG=$MODDIR/logs/$ID-STDERR.log
oldLOG=$MODDIR/logs/$ID-old.log
# > Verbose output goes here
VERLOG=$MODDIR/logs/$ID-verbose.log
oldVERLOG=$MODDIR/logs/$ID-verbose-old.log

# Start Logging verbosely
mv -f $VERLOG $oldVERLOG 2>/dev/null; mv -f $LOG $oldLOG 2>/dev/null
exec 2>$LOG
set -x 2>$VERLOG

########
# Main #
########
API=$(getprop ro.build.version.sdk)
PATH="/sbin/.magisk/busybox:/sbin/:$PATH"
alias aapt='$MODDIR/aapt'
alias sign='$MODDIR/zipsigner'
xml=/data/system/packages.xml
OVERLAYDIR=$MODDIR/overlays/quickswitchoverlay
NAVOVERLAYDIR=$MODDIR/overlays/qnav
RAND=$(echo $RANDOM | sed -r 's|^(...).*|\1|')
QNAV=
DID_MOUNT_RW=
NOBACK=

abort() {
  echo "qsError: $1"
  echo "$1" >&2
}

abortexit() {
  echo "qsError: $1"
  echo "$1" >&2
  get_logs
  exit 1
}

# Functions to check if dirs is mounted
is_mounted() {
  grep " `readlink -f $1` " /proc/mounts 2>/dev/null
  return $?
}

is_mounted_rw() {
  grep " `readlink -f $1` " /proc/mounts | grep " rw," 2>/dev/null
  return $?
}

mount_rw() {
  mount -o remount,rw $1
  DID_MOUNT_RW=$1
}

unmount_rw() {
  if [ "x$DID_MOUNT_RW" = "x$1" ]; then
    mount -o remount,ro $1
  fi
}

set_perms(){
  echo "\nSetting permissions..."
  chmod 644 $STEPDIR/*; chown 0:2000 $STEPDIR
  if [ ! "$1" == "com.android.systemui" ]; then
    chmod 755 $MODDIR/system/etc/; chmod 644 $PERMISSIONXMLDIR/*
    chmod 644 $WHITELISTXMLDIR/*;  chmod 755 $SYSTEMIZE_TARGET/*
    chmod 644 $SYSTEMIZE_TARGET/*/*
  fi
}

get_logs(){
  overlaylog=$(cmd overlay dump xyz.paphonb.quickstepswitcher.overlay)
  if [ "$overlaylog" ]; then
    echo "$overlaylog" > $MODDIR/logs/$ID-overlays.log
  else
    echo "Overlay not found" > $MODDIR/logs/$ID-overlays.log
  fi
  echo "---Device Info---" > $MODDIR/logs/$ID-vars.log
  grep "^ro.product.device[^#]" /system/build.prop | \
    sed 's/ro.product.device/DeviceCode/g' >> $MODDIR/logs/$ID-vars.log
  grep "^ro.product.model[^#]" /system/build.prop | \
    sed 's/ro.product.model/DeviceName/g' >> $MODDIR/logs/$ID-vars.log
  grep "^ro.build.type[^#]" /system/build.prop | \
    sed 's/ro.build.type/BuildType/g' >> $MODDIR/logs/$ID-vars.log
  grep "^ro.build.version.security_patch[^#]" /system/build.prop | \
    sed 's/ro.build.version.security_patch/SecurityPatch/g' \
      >> $MODDIR/logs/$ID-vars.log
  grep "^ro.product.cpu.abilist[^#]" /system/build.prop | \
    sed 's/ro.product.cpu.abilist/Arch/g' >> $MODDIR/logs/$ID-vars.log
  grep "^ro.build.version.sdk[^#]" /system/build.prop | \
    sed 's/ro.build.version.sdk/APIVer/g' >> $MODDIR/logs/$ID-vars.log
  grep "^ro.build.flavor[^#]" /system/build.prop | \
    sed 's/ro.build.flavor/BuildFlavor/g' >> $MODDIR/logs/$ID-vars.log
  echo "\n---ROM Info---" >> $MODDIR/logs/$ID-vars.log
  grep "^ro.build.host[^#]" /system/build.prop | \
    sed 's/ro.build.host/Host/g' >> $MODDIR/logs/$ID-vars.log
  grep "^ro.*.device[^#]" /system/build.prop >> $MODDIR/logs/$ID-vars.log
  echo -e "\n---Variables---" >> $MODDIR/logs/$ID-vars.log
  ( set -o posix ; set ) >> $MODDIR/logs/$ID-vars.log
  echo -e "\n---Magisk Version---" >> $MODDIR/logs/$ID-vars.log
  echo `grep "MAGISK_VER_CODE=" /data/adb/magisk/util_functions.sh | \
    sed "s/MAGISK_VER_CODE/MagiskVersion/"` >> $MODDIR/logs/$ID-vars.log
  echo -e "\n---Module Version---" >> $MODDIR/logs/$ID-vars.log
  echo `grep "versionCode=" $MODDIR/module.prop` >> $MODDIR/logs/$ID-vars.log
  find $MODDIR > $MODDIR/logs/find.log
  rm -rf /storage/emulated/0/Documents/$ID/*
  mkdir -p /storage/emulated/0/Documents/$ID
  cp -rf $MODDIR/logs/* /storage/emulated/0/Documents/$ID/
  echo "\nLogs copied to /sdcard/Documents/$ID..."
}

reset_provider(){
  setvars
  rm -rf $MODDIR/system
  rm -rf /data/resource-cache/overlays.list
  find /data/resource-cache/ -name *QuickstepSwitcherOverlay* -exec rm -rf {} \;
}

unmount_rw_stepdir(){
  if [ "$OEM" ];then
    is_mounted_rw " /oem" && unmount_rw /oem
    is_mounted_rw " /oem/OP" && unmount_rw /oem/OP
  fi
}

setvars(){
  MAGISK_VER_CODE=$(grep "MAGISK_VER_CODE=" /data/adb/magisk/util_functions.sh | awk -F = '{ print $2 }')
  if [ "$API" -ge 29 ]; then
    SUFFIX="/overlay/QuickstepSwitcherOverlay"
    case "$(getprop ro.product.brand) $(getprop ro.product.manufacturer)" in
      *samsung*) if [ ! -d /product/overlay ]; then
                   STEPDIR=$MODDIR/system/vendor$SUFFIX
                 else
                   STEPDIR=$MODDIR/system/product$SUFFIX
                 fi;;
      *) PRODUCT=true
          # Yay, magisk supports bind mounting /product now
          if [ $MAGISK_VER_CODE -ge "20000" ]; then
            STEPDIR=$MODDIR/system/product$SUFFIX
          else
            abort "Magisk v20 is required for users on Android 10"
            abortexit "Please update Magisk and try again."
          fi;;
    esac
  else
    SUFFIX="/overlay"
    if [ -d /oem/OP ]; then
      OEM=true
      is_mounted " /oem" || mount /oem
      is_mounted_rw " /oem" || mount_rw /oem
      is_mounted " /oem/OP" || mount /oem/OP
      is_mounted_rw " /oem/OP" || mount_rw /oem/OP
      STEPDIR=/oem/OP/OPEN_US/overlay/framework
    else
      PRODUCT=; OEM=
      STEPDIR=$MODDIR/system/vendor$SUFFIX
    fi
  fi

  if [ "$OEM" ];then
    is_mounted " /oem" || mount /oem
    is_mounted_rw " /oem" || mount_rw /oem
    is_mounted " /oem/OP" || mount /oem/OP
    is_mounted_rw " /oem/OP" || mount_rw /oem/OP
  fi

  # Assign misc variables
  PERMISSIONXMLDIR=$MODDIR/system/etc/permissions
  WHITELISTXMLDIR=$MODDIR/system/etc/sysconfig
  SYSTEMIZE_TARGET=$MODDIR/system/priv-app
}

switch_providers(){
  reset_provider

  echo "\nThe overlay will be copied to $STEPDIR..."

  # Create needed dirs
  while [ ! -d "$STEPDIR" ]; do
    setvars
    mkdir -p $STEPDIR
  done

  if [ ! "$1" == "com.android.systemui" ]; then
    mkdir -p $SYSTEMIZE_TARGET/QuickSwitch-${1}-${RAND}
    mkdir -p $MODDIR/system/etc/permissions
    mkdir -p $MODDIR/system/etc/sysconfig
    package=$(echo $1 | cut -d- -f2-)
    sysapk=$(grep "updated-package name=\"$package\"" $xml | grep -o 'codePath=.*$' | cut -d\" -f2)
    [ -z $sysapk ] && sysapk=$(grep "package name=\"$package\"" $xml | grep -o 'codePath=.*$' | cut -d\" -f2)
    dataapktmp=$(ls /data/app/ | grep $1)
    dataapk="/data/app/${dataapktmp}/base.apk"
    if [ $dataapktmp ]; then
      origdir="$dataapk"
    else
      origdir="${sysapk}/*.apk"
    fi
    if [ -z $sysapk ] && [ -z $dataapktmp ]; then
      abortexit "Could not systemise launcher..."
    fi
    cp -rf $origdir \
      $SYSTEMIZE_TARGET/QuickSwitch-"${1}"-"${RAND}"/QuickSwitch-"${1}"-"${RAND}".apk

    perms=$(aapt d permissions $origdir | grep "uses-permission:" | \
     sed -r "s|.*='(.*)'|\1|")
    permissions=$(echo "$perms" | \
     sed -re "s|  ||g; s|^|        <permission name=\"|; s|$|\"/>|")

    echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<permissions>
    <privapp-permissions package=\"${1}\">
$permissions
    </privapp-permissions>
</permissions>" > $PERMISSIONXMLDIR/privapp-permissions-$1.xml

    echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<config>
    <hidden-api-whitelisted-app package=\"${1}\"/>
</config>" > $WHITELISTXMLDIR/$1-hiddenapi-package-whitelist.xml
  fi

  echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<resources>
	<string name=\"config_recentsComponentName\">$1/com.android.quickstep.RecentsActivity</string>
</resources>" > $OVERLAYDIR/overlay/values/strings.xml

  if [ $NOBACK ]; then
    echo "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<resources>
	<dimen name=\"config_backGestureInset\">0dp</dimen>
</resources>" > $OVERLAYDIR/overlay/values/config.xml
  else
    [ -f $OVERLAYDIR/overlay/values/config.xml ] && rm $OVERLAYDIR/overlay/values/config.xml
  fi

  aapt p -f -v -M ${OVERLAYDIR}/AndroidManifest.xml \
                -I /system/framework/framework-res.apk -S ${OVERLAYDIR}/overlay/ \
                -F ${MODDIR}/unsigned.apk &>$MODDIR/logs/aapt.log

  if [ "$QNAV" ]; then
    aapt p -f -v -M ${NAVOVERLAYDIR}/AndroidManifest.xml \
                -I /system/framework/framework-res.apk -S ${NAVOVERLAYDIR}/overlay/ \
                -F ${MODDIR}/qnav-unsigned.apk &>>$MODDIR/logs/aapt.log
  fi

# currently, navbar height support hasn't been added to the app, so no need to check for this yet.
#  [ -f $OVERLAYDIR/overlay/values/dimens.xml ] && rm $OVERLAYDIR/overlay/values/dimens.xml

  if [ -s ${MODDIR}/unsigned.apk ]; then
    sign ${MODDIR}/unsigned.apk ${MODDIR}/signed.apk
    cp -rf ${MODDIR}/signed.apk ${STEPDIR}/QuickstepSwitcherOverlay.apk
    [ ! -s ${MODDIR}/signed.apk ] && cp -rf ${MODDIR}/unsigned.apk ${STEPDIR}/QuickstepSwitcherOverlay.apk
    rm -rf ${MODDIR}/signed.apk ${MODDIR}/unsigned.apk
  else
    abort "Overlay not created!"
    abort "This is generally a rom incompatibility,"
    abortexit "currently I'm unsure how to fix this."
  fi

  if [ "$QNAV" ]; then
    sign ${MODDIR}/qnav-unsigned.apk ${MODDIR}/qnav-signed.apk
    cp -rf ${MODDIR}/qnav-signed.apk ${STEPDIR}/QuickSwitchQNavOverlay.apk
    if [ ! -f ${MODDIR}/qnav-signed.apk ]; then
      cp -rf ${MODDIR}/qnav-unsigned.apk ${STEPDIR}/QuickSwitchQNavOverlay.apk
    fi
    rm -rf ${MODDIR}/qnav-unsigned.apk ${MODDIR}/qnav-signed.apk
  fi

  if [ -s ${STEPDIR}/QuickstepSwitcherOverlay.apk ]; then
    echo "\nOverlay successfully copied..."
  else
    abortexit "The overlay was not copied, please send logs to the developer."
  fi

  set_perms $1

# Lets save this for a rainy day
#  SDK=$(getprop ro.build.version.sdk)
#  SAMMY=$(getprop ro.product.brand)

#  if [[ "$SDK" = 29 ]] && \
#     [[ "$SAMMY" == *"samsung"* ]]; then
#    for i in $(cmd overlay list | grep navbar | awk '{print $NF}' | \
#        egrep -v com.samsung.internal.systemui.navbar.gestural_no_hint); do
#      cmd overlay disable $i
#    done
#    cmd overlay enable com.samsung.internal.systemui.navbar.gestural_no_hint
#  fi

# lets not add this just yet as it can cause crashes in certain circumstances
#  if [ ! "$1" == "com.android.systemui" ]; then
#    echo "pm set-home-activity $1" > $MODDIR/service.sh
#    echo 'rm -rf $0' >> $MODDIR/service.sh
#  fi
}

print_modname() {
  # @Skittles9823 made this ascii and is way to proud of it
  echo " "
  echo "       _____       "
  echo "   __ |     | __   "
  echo "  |  ||     ||  |  "
  echo "  |  ||     ||  |  "
  echo "  |__||     ||__|  "
  echo "      |_____|      "
  echo "    QuickSwitch    "
  echo "                   "
  echo " The Lawnchair Team"
  echo " "
}

print_modname

resetprop ro.recents.grid false
sed -i "/*ro.recents.grid*/d" $MODDIR/system.prop

for arg in $(echo ${@}); do
  args=$(echo $arg | tr '=' ' ')
  opt1=$(echo $args | awk '{ print $1 }')
  opt2=$(echo $args | awk '{ print $2 }')
  case "$opt1" in
    --reset) reset_provider
      echo "The recents provider has been reset to default."
      continue;;
    --qnav) echo "Installing Android 10 navigation bar overlay..."
      QNAV=true
      continue;;
    --grid) resetprop ro.recents.grid true
      echo "ro.recents.grid=true" >> $MODDIR/system.prop
      continue;;
    --noback) NOBACK=true
      continue;;
    --ch) switch_providers "$opt2"
      continue;;
  esac
done

unmount_rw_stepdir

get_logs

echo "\nPlease reboot for changes to take effect."

exit $?
