#!/bin/bash
set -e

cyan='\033[1;36m'
reset='\033[0m'

echo -e "\n${cyan}Automatic user folder backup tool${reset}"
echo "!!!USE IT AT YOUR OWN RISK!!!!"
echo "When works, this will:"
echo "- Copy user folders from macOS Recovery"
echo "- Skip hidden folders (starting with .), including .Trash, .cache, etc."
echo "- Skip the Library folder (includes Mail, Preferences, etc.)"
echo "- Skip system users: Guest, Shared"
echo "You should back up important or hidden data (Mail, preferences) manually if needed."
echo

read -p "Do you want to run backup automatically? [Y/n]: " run_auto
[[ "$run_auto" != "Y" && "$run_auto" != "y" ]] && exit 0

echo -e "\n${cyan}Backup drive must be disconnected for now.${reset}"
echo "When asked, connect ONLY the drive you want to erase and back up to."

read -p "Do you understand that an external drive will be completely ERASED? [y/N]: " confirm1
[[ "$confirm1" != "y" && "$confirm1" != "Y" ]] && exit 1

read -p "Are you absolutely sure you want to continue? [y/N]: " confirm2
[[ "$confirm2" != "y" && "$confirm2" != "Y" ]] && exit 1

# Detect newly connected disk
echo -e "\nCurrent disk list (before connection):"
BEFORE=$(diskutil list | grep "^/dev/disk" | awk '{print $1}')
echo "$BEFORE"

echo -e "\nPlease connect your external backup drive now. Waiting 10 seconds..."
sleep 10

echo -e "\nUpdated disk list (after connection):"
AFTER=$(diskutil list | grep "^/dev/disk" | awk '{print $1}')
echo "$AFTER"

echo -e "\nDetecting new disks..."
DISKS=$(comm -13 <(echo "$BEFORE") <(echo "$AFTER"))
echo -e "Newly detected disks:\n$DISKS"

TARGET_DISK=""
for d in $DISKS; do
  if diskutil info "$d" | grep -q "External"; then
    TARGET_DISK="$d"
    echo -e "Auto-detected external disk: $d"
    diskutil info "$d" | grep -E "Device Node|Media Name|Protocol|Internal|Removable|Mount Point"
    break
  fi
done

if [[ -z "$TARGET_DISK" ]]; then
  echo -e "\n❗ Auto-detection failed."
  echo "Here's a current list of connected disks:"
  diskutil list | grep '^/dev/disk'

  read -p "Enter the disk identifier you want to use (e.g., /dev/disk2): " manual_disk
  if ! diskutil info "$manual_disk" | grep -q "External"; then
    echo "❌ That disk does not appear to be external. Aborting."
    exit 1
  fi
  TARGET_DISK="$manual_disk"
fi

# Prevent erasing internal or virtual disks
# Check disk properties before formatting
IS_EXTERNAL=$(diskutil info "$TARGET_DISK" | grep -i "Device Location:" | grep -qi "external" && echo "yes" || echo "no")
IS_VIRTUAL=$(diskutil info "$TARGET_DISK" | grep -i "Virtual:" | grep -qi "yes" && echo "yes" || echo "no")
IS_REMOVABLE=$(diskutil info "$TARGET_DISK" | grep -i "Removable Media:" | grep -qi "removable" && echo "yes" || echo "no")

if [[ "$IS_EXTERNAL" != "yes" || "$IS_VIRTUAL" == "yes" || "$IS_REMOVABLE" != "yes" ]]; then
  echo "❌ Selected disk is not a removable external physical drive. Aborting for safety."
  exit 1
fi

if [[ "$TARGET_DISK" == "/dev/disk0" ]]; then
  echo "❌ Refusing to erase internal disk0!"
  exit 1
fi

echo -e "\nSelected disk to be formatted: ${cyan}$TARGET_DISK${reset}"
read -p "Erase and format this drive as APFS (named BackupDrive)? [y/N]: " format_confirm
[[ "$format_confirm" != "y" && "$format_confirm" != "Y" ]] && exit 1

diskutil eraseDisk APFS BackupDrive "$TARGET_DISK"



DEST="/Volumes/BackupDrive"
[[ ! -d "$DEST" ]] && { echo "❌ BackupDrive not mounted. Aborting."; exit 1; }

# Locate user folder root (only volumes ending in "- Data")
USER_ROOT=""
for VOL in /Volumes/*; do
  if [[ "$VOL" == *"- Data" && -d "$VOL/Users" ]]; then
    USER_ROOT="$VOL/Users"
    break
  fi
done

if [[ -z "$USER_ROOT" ]]; then
  echo "❌ Could not locate a valid user folder under any '*- Data' volume."
  exit 1
fi

echo -e "\nDetected user folder location: ${cyan}$USER_ROOT${reset}"

# Filter real user directories only
USER_LIST=$(find "$USER_ROOT" -type d -maxdepth 1 -mindepth 1 \
  -exec basename {} \; | grep -vE '^(Guest|Shared|\.localized|\..*)$' || true)

if [[ -z "$USER_LIST" ]]; then
  echo "❌ No valid user folders found. Aborting."
  exit 1
fi

echo "Available user folders:"
echo "$USER_LIST"

read -p "Type username to back up or type 'all' for all users: " selected_user

# Ensure rsync_universal is present
if [[ ! -x "./rsync_universal" ]]; then
  echo "❌ ./rsync_universal not found or not executable. Aborting."
  exit 1
fi

EXCLUDES=(
  "--exclude=Library/"
  "--exclude=.*"
  "--exclude=.Trash/"
  "--exclude=.cache/"
  "--exclude=.fseventsd/"
  "--exclude=.DocumentRevisions-V100/"
  "--exclude=.Spotlight*/"
)

# Backup logic
if [[ "$selected_user" == "all" ]]; then
  for user in $USER_LIST; do
    SRC="$USER_ROOT/$user/"
    DEST_DIR="$DEST/${user}_Backup"
    echo -e "\nBacking up ${cyan}$SRC${reset} to ${cyan}$DEST_DIR${reset}..."
    ./rsync_universal -aEHX --no-compress --inplace --progress "${EXCLUDES[@]}" "$SRC" "$DEST_DIR"
  done
else
  if [[ ! -d "$USER_ROOT/$selected_user" ]]; then
    echo "❌ User folder $USER_ROOT/$selected_user not found."
    exit 1
  fi
  SRC="$USER_ROOT/$selected_user/"
  DEST_DIR="$DEST/${selected_user}_Backup"
  echo -e "\nBacking up ${cyan}$SRC${reset} to ${cyan}$DEST_DIR${reset}..."
  ./rsync_universal -aEHX --no-compress --inplace --progress "${EXCLUDES[@]}" "$SRC" "$DEST_DIR"
fi

echo -e "\n${cyan}✅ Backup complete.${reset}"