#!/sbin/sh
# Copyright (C) 2018-2026 PitchBlack Recovery <pitchblackrecovery@gmail.com>
# Copyright (C) 2020 osm0sis, Dees_Troy and topjohnwu
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#      http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

OUTFD=/proc/self/fd/$2
ZIPFILE="$3"

show_progress() { echo "progress $1 $2" > $OUTFD; }

ui_print() {
  if $BOOTMODE; then
    echo "$1"
  else
    echo -e "ui_print $1\nui_print" >> $OUTFD
  fi
}

abort() { 
  ui_print " " 
  ui_print "|------------Error Occurred!------------|"
  ui_print "Error: $1" 
  exit 1 
}

# --- Environment Setup ---
BOOTMODE=false
ps | grep zygote | grep -v grep >/dev/null && BOOTMODE=true
$BOOTMODE || ps -A 2>/dev/null | grep zygote | grep -v grep >/dev/null && BOOTMODE=true

# --- Configuration (Injected by Makefile) ---
IS_AB=true
IS_VENDOR_BOOT=true
IS_RECOVERY_AS_BOOT=false

show_progress 0.1000000, 0
ui_print "|---------------------------------------------|"
ui_print "|---------PitchBlack Recovery Project---------|"
ui_print "|-------------------v4.0----------------------|"
ui_print "|---------------------------------------------|"
ui_print "|---------------------------------------------|"
ui_print "|--------------Brought To You By--------------|"
ui_print "|---------------------------------------------|"
ui_print "|---------------PitchBlack Team---------------|"
ui_print "|---------------------------------------------|"
ui_print "|---------------------------------------------|"
ui_print "|            Based on TWRP v3.7.1_x           |"
ui_print "|---------------------------------------------|"

# --- Temp Directory Setup ---
tmp=/dev/tmp/pbrp-install
rm -rf $tmp
mkdir -p $tmp

# --- Partition Detection ---
partdir="/dev/block/by-name"
[ -d "/dev/block/bootdevice/by-name" ] && partdir="/dev/block/bootdevice/by-name"
[ ! -d "$partdir" ] && abort "Partition block directory not found!"

ui_print "|-----------Unpacking the installer-----------|"
unzip -o "$ZIPFILE" -d $tmp > /dev/null || abort "Failed to extract zip!"

cd $tmp

# --- Dynamic Payload Detection (Largest File Priority) ---
# 1. Largest CPIO (Ramdisk)
recoverycpio=$(ls -1S *.cpio 2>/dev/null | head -n 1)
# 2. Largest Recovery Image
recoveryimg=$(ls -1S *recovery*.img 2>/dev/null | head -n 1)
# 3. Largest Vendor Boot Image
vendorbootimg=$(ls -1S *vendor*boot*.img 2>/dev/null | head -n 1)

if [ -z "$recoverycpio" ] && [ -z "$recoveryimg" ] && [ -z "$vendorbootimg" ]; then
  abort "No PBRP payload (cpio or img) found in zip!"
fi

tool=$tmp/magiskboot
chmod 755 $tool

# --- Define Slots ---
if [ "$IS_AB" == "true" ]; then
  SLOTS="_a _b"
else
  SLOTS=""
fi

# =========================================================
# LOGIC 1: VENDOR_BOOT (Smart Detection)
# =========================================================
if [ "$IS_VENDOR_BOOT" == "true" ]; then
  
  target_slots="$SLOTS"
  [ -z "$target_slots" ] && target_slots="non_ab"

  for slot in $target_slots; do
    [ "$slot" == "non_ab" ] && slot=""
    target="${partdir}/vendor_boot${slot}"
    
    ui_print "|------------Doing Work on slot $slot------------|"
    
    # 1. Dump Stock
    dd bs=1048576 if=$target of=current-vb.img 2>/dev/null || abort "Failed to dump vendor_boot!"
    
    # 2. Unpack Stock
    $tool unpack -h current-vb.img >/dev/null || abort "Failed to unpack current vendor_boot!"
    
    # 3. Detect Target Ramdisk Name
    # We look for what file magiskboot actually created from the stock image.
    # We prioritize specific recovery names, then fall back to generic.
    if [ -f "vendor_ramdisk_recovery.cpio" ]; then
        TARGET_RAMDISK_NAME="vendor_ramdisk_recovery.cpio"
    elif [ -f "ramdisk_recovery.cpio" ]; then
        TARGET_RAMDISK_NAME="ramdisk_recovery.cpio"
    elif [ -f "ramdisk.cpio" ]; then
        TARGET_RAMDISK_NAME="ramdisk.cpio"
    else
        # Extremely rare case: maybe just 'ramdisk' without extension?
        TARGET_RAMDISK_NAME=$(ls -1S *.cpio 2>/dev/null | head -n 1)
        if [ -z "$TARGET_RAMDISK_NAME" ]; then
             abort "Stock vendor_boot unpacked but no ramdisk found!"
        fi
    fi
    
    ui_print "|- Detected Stock Ramdisk: $TARGET_RAMDISK_NAME"

    # 4. Unpack New (PBRP) Image to get Source
    mkdir -p new_extract
    cd new_extract
    $tool unpack -h ../$vendorbootimg >/dev/null 2>&1
    
    # Find Source Ramdisk (Largest CPIO in PBRP image)
    SOURCE_RAMDISK=$(ls -1S *.cpio 2>/dev/null | head -n 1)
    
    if [ -z "$SOURCE_RAMDISK" ]; then 
        abort "Could not find any ramdisk inside the new PBRP image!" 
    fi
    
    # 5. Overwrite the DETECTED stock name
    cp -f "$SOURCE_RAMDISK" ../$TARGET_RAMDISK_NAME 2>/dev/null
    
    cd ..
    rm -rf new_extract
    
    # 6. Repack
    $tool repack current-vb.img >/dev/null || abort "Failed to repack vendor_boot!"
    
    ui_print "|------------Installing to vendor_boot slot $slot------------|"
    cat new-boot.img > $target || abort "Failed to write to $target"
    
    # Cleanup
    $tool cleanup
    rm -f new-boot.img current-vb.img
  done

# =========================================================
# LOGIC 2: RECOVERY AS BOOT (Smart Detection)
# =========================================================
elif [ "$IS_AB" == "true" ] && [ "$IS_RECOVERY_AS_BOOT" == "true" ]; then
  
  if [ -z "$recoverycpio" ]; then abort "Ramdisk CPIO not found in zip!"; fi

  for slot in $SLOTS; do
    target="${partdir}/boot${slot}"
    
    ui_print "|------------Doing Work on slot $slot------------|"
    
    dd bs=1048576 if=$target of=boot.img 2>/dev/null || abort "Failed to dump boot!"
    $tool unpack -h boot.img >/dev/null || abort "Failed to unpack boot!"
    
    # Detect what boot.img named the ramdisk (usually ramdisk.cpio)
    if [ -f "ramdisk.cpio" ]; then
        TARGET_RAMDISK_NAME="ramdisk.cpio"
    else
        TARGET_RAMDISK_NAME=$(ls -1S *.cpio 2>/dev/null | head -n 1)
    fi
    
    if [ -z "$TARGET_RAMDISK_NAME" ]; then abort "No ramdisk found in stock boot.img!"; fi
    
    # Magisk Patch (Skip Initramfs)
    $tool hexpatch kernel 77616E745F696E697472616D6673 736B69705F696E697472616D6673
    
    # Overwrite the DETECTED name
    cp -f "$recoverycpio" "$TARGET_RAMDISK_NAME"
    
    $tool repack boot.img >/dev/null || abort "Failed to repack boot!"
    
    ui_print "|------------Installing to boot slot $slot------------|"
    cat new-boot.img > $target || abort "Failed to write to $target"
    
    $tool cleanup
    rm -f new-boot.img boot.img
  done

# =========================================================
# LOGIC 3: DEDICATED RECOVERY (Simple Flash)
# =========================================================
else
  target_slots="$SLOTS"
  [ -z "$target_slots" ] && target_slots="non_ab"
  
  for slot in $target_slots; do
    [ "$slot" == "non_ab" ] && slot=""
    target="${partdir}/recovery${slot}"
    
    ui_print "|------------Installing to recovery slot $slot------------|"
    
    if [ -f "$recoveryimg" ]; then
        cat "$recoveryimg" > "$target" || abort "Failed to flash recovery!"
    else
        abort "recovery.img not found in zip!"
    fi
  done
fi

show_progress 0.8000000, 0

# --- Copy Tools ---
ui_print "|------------Unpacking The Tools--------------|"
if [ -d "$tmp/PBRP/tools" ]; then
  mkdir -p /sdcard/PBRP
  cp -r $tmp/PBRP/tools /sdcard/PBRP/ 2>/dev/null
  ui_print "|--------Finished Unpacking The Tools---------|"
else
  ui_print "|-----------Tools not found in zip------------|"
fi

ui_print "|---------------------------------------------|"
ui_print "|---------------------------------------------|"
ui_print "|                  Thank You                  |"
if [[ ! -f "/sbin/keycheck" ]]; then
  ui_print "|   Reboot to PitchBlack Recovery Manually    |"
fi
ui_print "|---------------------------------------------|"
ui_print "|------------Installation finished!-----------|"

cd /
rm -rf $tmp
exit 0
