#!/bin/bash
#
# Pull Stegasoo image from SD card
# Auto-detects SD card, copies with progress, shrinks, and compresses
#
# Usage: ./pull-image.sh [output-name] [device]
#        Output will be: stegasoo-rpi-YYYYMMDD.img.zst (or custom name)
#        Use .img extension to skip compression: ./pull-image.sh foo.img
#
# If device is specified, skips auto-detection (useful for large drives)
#

set -e

RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
BOLD='\033[1m'
NC='\033[0m'

# Check for required tools
for cmd in dd pv zstd lsblk; do
    if ! command -v $cmd &> /dev/null; then
        echo -e "${RED}Error: $cmd is required but not installed.${NC}"
        exit 1
    fi
done

# Check for root
if [ "$EUID" -ne 0 ]; then
    echo -e "${RED}Error: Must run as root (sudo)${NC}"
    exit 1
fi

# Output filename and optional device
if [ -n "$1" ]; then
    OUTPUT="$1"
else
    OUTPUT="stegasoo-rpi-$(date +%Y%m%d).img.zst"
fi
MANUAL_DEVICE="$2"

# Check if output ends in .img (skip compression) or .zst (compress)
SKIP_COMPRESS=false
if [[ "$OUTPUT" == *.img ]]; then
    IMG_FILE="$OUTPUT"
    SKIP_COMPRESS=true
elif [[ "$OUTPUT" == *.zst ]]; then
    IMG_FILE="${OUTPUT%.zst}"
else
    # No recognized extension, add .img.zst
    IMG_FILE="${OUTPUT}.img"
    OUTPUT="${OUTPUT}.img.zst"
fi

echo -e "${BLUE}"
echo "╔═══════════════════════════════════════════════════════════════╗"
echo "║              Stegasoo SD Card Image Puller                    ║"
echo "╚═══════════════════════════════════════════════════════════════╝"
echo -e "${NC}"

# Use manual device or auto-detect
if [ -n "$MANUAL_DEVICE" ]; then
    # Manual device specified
    if [ ! -b "$MANUAL_DEVICE" ]; then
        echo -e "${RED}Error: $MANUAL_DEVICE is not a block device${NC}"
        exit 1
    fi
    SELECTED="$MANUAL_DEVICE"
    echo -e "Using specified device: ${YELLOW}$SELECTED${NC}"
    echo ""
    lsblk "$SELECTED" -o NAME,SIZE,TYPE,MODEL
    echo ""
else
    # Auto-detect SD card candidates
    # Looking for: USB/removable, 8-128GB, not mounted as root filesystem
    echo -e "${BOLD}Scanning for SD cards...${NC}"
    echo ""

    declare -a CANDIDATES
    declare -a CANDIDATE_INFO

    while IFS= read -r line; do
        DEV=$(echo "$line" | awk '{print $1}')
        SIZE=$(echo "$line" | awk '{print $2}')
        TYPE=$(echo "$line" | awk '{print $3}')
        TRAN=$(echo "$line" | awk '{print $4}')
        MODEL=$(echo "$line" | awk '{print $5" "$6" "$7}' | xargs)

        # Skip if it's the root filesystem
        if mount | grep -q "^/dev/${DEV}[0-9]* on / "; then
            continue
        fi

        # Skip if any partition is mounted as root
        ROOT_DEV=$(mount | grep " on / " | awk '{print $1}' | sed 's/[0-9]*$//')
        if [[ "/dev/$DEV" == "$ROOT_DEV" ]]; then
            continue
        fi

        # Get size in bytes for reliable comparison
        SIZE_BYTES=$(lsblk -b -d -o SIZE -n "/dev/$DEV" 2>/dev/null | tr -d ' ')
        SIZE_GB_INT=$((SIZE_BYTES / 1073741824))  # 1024^3

        # Check if size is in SD card range (8GB - 128GB)
        if [ "$SIZE_GB_INT" -ge 8 ] && [ "$SIZE_GB_INT" -le 128 ]; then
            CANDIDATES+=("/dev/$DEV")
            CANDIDATE_INFO+=("$SIZE $TYPE ${TRAN:-???} $MODEL")
        fi
    done < <(lsblk -d -o NAME,SIZE,TYPE,TRAN,MODEL -n | grep "disk")

    if [ ${#CANDIDATES[@]} -eq 0 ]; then
        echo -e "${RED}No SD card candidates found.${NC}"
        echo "Looking for USB/removable disks between 8GB and 128GB."
        echo ""
        echo "Available disks:"
        lsblk -d -o NAME,SIZE,TYPE,TRAN,MODEL
        echo ""
        echo -e "${YELLOW}Tip: Specify device manually: $0 output.img.zst /dev/sdX${NC}"
        exit 1
    fi

    echo -e "${GREEN}Found ${#CANDIDATES[@]} candidate(s):${NC}"
    echo ""

    for i in "${!CANDIDATES[@]}"; do
        echo -e "  ${BOLD}[$((i+1))]${NC} ${CANDIDATES[$i]} - ${CANDIDATE_INFO[$i]}"
    done

    echo ""

    if [ ${#CANDIDATES[@]} -eq 1 ]; then
        SELECTED="${CANDIDATES[0]}"
        echo -e "Auto-selected: ${YELLOW}$SELECTED${NC}"
    else
        read -p "Select device [1-${#CANDIDATES[@]}]: " -r
        if [[ ! $REPLY =~ ^[0-9]+$ ]] || [ "$REPLY" -lt 1 ] || [ "$REPLY" -gt ${#CANDIDATES[@]} ]; then
            echo -e "${RED}Invalid selection.${NC}"
            exit 1
        fi
        SELECTED="${CANDIDATES[$((REPLY-1))]}"
    fi
fi

# Show partitions
echo ""
echo -e "${BOLD}Partitions on $SELECTED:${NC}"
lsblk "$SELECTED" -o NAME,SIZE,FSTYPE,LABEL,MOUNTPOINT
echo ""

# Final confirmation
echo -e "${RED}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${RED}║  WARNING: This will read the ENTIRE device:                   ║${NC}"
echo -e "${RED}║  $SELECTED                                                  ║${NC}"
echo -e "${RED}╚═══════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "Output: ${YELLOW}$OUTPUT${NC}"
echo ""
read -p "Continue? [y/N] " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
    echo "Aborted."
    exit 1
fi

# Get device size for pv
DEV_SIZE=$(blockdev --getsize64 "$SELECTED")

echo ""
echo -e "${GREEN}[1/3]${NC} Copying image from $SELECTED..."
dd if="$SELECTED" bs=4M status=none | pv -s "$DEV_SIZE" > "$IMG_FILE"
sync

echo ""
echo -e "${GREEN}[2/3]${NC} Shrinking image..."
if command -v pishrink.sh &> /dev/null; then
    pishrink.sh "$IMG_FILE"
elif [ -f "./pishrink.sh" ]; then
    bash ./pishrink.sh "$IMG_FILE"
elif [ -f "../pishrink.sh" ]; then
    bash ../pishrink.sh "$IMG_FILE"
else
    echo -e "${YELLOW}pishrink.sh not found, skipping shrink step.${NC}"
    echo "Download from: https://github.com/Drewsif/PiShrink"
fi

echo ""
if [ "$SKIP_COMPRESS" = true ]; then
    echo -e "${GREEN}[3/3]${NC} Skipping compression (.img output)"
    FINAL_SIZE=$(du -h "$IMG_FILE" | awk '{print $1}')
    OUTPUT="$IMG_FILE"
else
    echo -e "${GREEN}[3/3]${NC} Compressing with zstd..."
    pv "$IMG_FILE" | zstd -19 -T0 -q > "$OUTPUT"
    rm -f "$IMG_FILE"
    FINAL_SIZE=$(du -h "$OUTPUT" | awk '{print $1}')
fi

echo ""
echo -e "${GREEN}╔═══════════════════════════════════════════════════════════════╗${NC}"
echo -e "${GREEN}║                    Image Complete!                            ║${NC}"
echo -e "${GREEN}╚═══════════════════════════════════════════════════════════════╝${NC}"
echo ""
echo -e "Output: ${YELLOW}$OUTPUT${NC}"
echo -e "Size:   ${YELLOW}$FINAL_SIZE${NC}"
echo ""
