#!/usr/bin/env bash
# Revision: 2
# Run on the Proxmox host when shrink_request.json appears in the provisioning dir.
# Runs PiShrink on the requested backup image (shrink or shrink+compress).
# Requires PiShrink on host (scripts/install-pishrink-on-host.sh). Triggered by cm4-shrink.path.

set -e
PROV_DIR="${CM4_PROVISIONING_DIR:-/var/lib/cm4-provisioning}"
REQUEST_FILE="$PROV_DIR/shrink_request.json"
STATUS_FILE="$PROV_DIR/shrink_status.json"
[[ -f /opt/cm4-provisioning/env ]] && source /opt/cm4-provisioning/env
BACKUPS_DIR="${BACKUPS_DIR:-$PROV_DIR/backups}"
PISHRINK="${PISHRINK_SCRIPT:-/usr/local/bin/pishrink.sh}"
SHRINK_TIMEOUT="${SHRINK_TIMEOUT:-2100}"

write_status() {
    local phase="$1" name="$2" message="$3" error="$4"
    printf '{"phase":"%s","name":"%s","message":"%s","error":%s,"updated":%s}\n' \
        "$phase" "$name" "$message" \
        "$([ -n "$error" ] && echo "\"${error//\"/\\\"}\"" || echo "null")" \
        "$(date +%s)" > "$STATUS_FILE"
}

[[ -f "$REQUEST_FILE" ]] || { echo "No request file"; exit 0; }

# Parse request
NAME=$(python3 -c "import json; print(json.load(open('$REQUEST_FILE')).get('name',''))")
ACTION=$(python3 -c "import json; print(json.load(open('$REQUEST_FILE')).get('action','shrink'))")
FORMAT=$(python3 -c "import json; print(json.load(open('$REQUEST_FILE')).get('format','xz'))")
rm -f "$REQUEST_FILE"

# Validate
if [[ -z "$NAME" ]]; then
    write_status "error" "" "" "Missing name in request"
    exit 0
fi
if [[ "$NAME" != "${NAME##*/}" ]] || [[ "$NAME" == *..* ]]; then
    write_status "error" "$NAME" "" "Invalid name"
    exit 0
fi
if [[ ! "$NAME" =~ \.img$ ]]; then
    write_status "error" "$NAME" "" "Only .img files can be shrunk"
    exit 0
fi
PATH_FILE="$BACKUPS_DIR/$NAME"
if [[ ! -f "$PATH_FILE" ]]; then
    write_status "error" "$NAME" "" "File not found"
    exit 0
fi

if [[ ! -x "$PISHRINK" ]]; then
    write_status "error" "$NAME" "" "PiShrink not installed on host. Run scripts/install-pishrink-on-host.sh"
    exit 0
fi

write_status "running" "$NAME" "Shrinking…" ""
OPTS=(-n)
if [[ "$ACTION" == "compress" ]]; then
    if [[ "$FORMAT" == "gz" ]] || [[ "$FORMAT" == "gzip" ]]; then
        OPTS+=(-z -a)
    else
        OPTS+=(-Z -a)
    fi
fi

cd "$BACKUPS_DIR" || exit 1
if timeout "$SHRINK_TIMEOUT" "$PISHRINK" "${OPTS[@]}" "$NAME" 2>&1; then
    if [[ "$ACTION" == "compress" ]]; then
        ext=".xz"
        [[ "$FORMAT" == "gz" ]] || [[ "$FORMAT" == "gzip" ]] && ext=".gz"
        write_status "done" "$NAME" "Compressed to ${NAME}${ext}" ""
    else
        write_status "done" "$NAME" "Shrunk $NAME" ""
    fi
else
    rc=$?
    write_status "error" "$NAME" "" "PiShrink failed (exit $rc)"
fi
