#!/usr/bin/env zsh

set -euo pipefail

PATH_TO_BACKUPGPG_KEY=${PATH_TO_BACKUPGPG_KEY:-}
PATH_TO_BACKUP_FILE=${PATH_TO_BACKUP_FILE:-}
PATH_TO_OUTPUT_DIR=${PATH_TO_OUTPUT_DIR:-}

KEEP=false

# TIL You can do these kind of scripts.
usage() {
  cat <<EOF
Usage: $0 [-f <backup-file>] [-k <private-key-file>] [-o <output-dir>] [--keep]

Decrypt and unpack a .gz.gpg backup file for inspection. The script will
create a temporary GNUPGHOME (if a key is provided), decrypt the file, and
if needed gunzip it to produce a .sql file. The resulting SQL file path will
be printed and a short preview will be shown.

Options:
  -f <file>    Path to the .sql.gz.gpg backup file (or set PATH_TO_BACKUP_FILE)
  -k <key>     Path to a private key file to import (optional; or set PATH_TO_BACKUPGPG_KEY)
  -o <dir>     Output directory for the final .sql file (defaults to current working directory)
  --keep       Keep temporary files (do not delete temp GNUPGHOME/dir)
  -h, --help   Show this message
EOF
  exit 1
}

# Simple arg parsing to allow flags
while [[ $# -gt 0 ]]; do
  case "$1" in
    -f)
      PATH_TO_BACKUP_FILE="$2"; shift 2;;
    -k)
      PATH_TO_BACKUPGPG_KEY="$2"; shift 2;;
    -o)
      PATH_TO_OUTPUT_DIR="$2"; shift 2;;
    --keep)
      KEEP=true; shift;;
    -h|--help)
      usage;;
    *)
      echo "Unknown argument: $1" >&2; usage;;
  esac
done

if [[ -z "$PATH_TO_BACKUP_FILE" ]]; then
  echo "Error: no backup file provided." >&2
  usage
fi

if [[ ! -f "$PATH_TO_BACKUP_FILE" ]]; then
  echo "Error: backup file does not exist: $PATH_TO_BACKUP_FILE" >&2
  exit 2
fi

command -v gpg >/dev/null 2>&1 || { echo "gpg not found in PATH" >&2; exit 3; }
command -v gunzip >/dev/null 2>&1 || { echo "gunzip not found in PATH" >&2; exit 3; }
command -v file >/dev/null 2>&1 || { echo "file command not found in PATH" >&2; exit 3; }

TMPDIR=$(mktemp -d)
trap '[[ "$KEEP" = false ]] && rm -rf "$TMPDIR"' EXIT

# If a key is provided, use an isolated GNUPGHOME so we don't touch the user's keyring.
if [[ -n "$PATH_TO_BACKUPGPG_KEY" ]]; then
  if [[ ! -f "$PATH_TO_BACKUPGPG_KEY" ]]; then
    echo "Private key file not found: $PATH_TO_BACKUPGPG_KEY" >&2
    exit 4
  fi
  export GNUPGHOME="$TMPDIR/gnupg"
  # Create GNUPGHOME and explicitly set secure permissions
  mkdir -p "$GNUPGHOME"
  chmod 0700 "$GNUPGHOME"
  echo "Importing provided private key into temporary GNUPGHOME..."
  gpg --batch --import "$PATH_TO_BACKUPGPG_KEY" >/dev/null 2>&1
fi

# Determine output directory: prefer PATH_TO_OUTPUT_DIR, otherwise current directory
if [[ -n "$PATH_TO_OUTPUT_DIR" ]]; then
  OUTDIR="$PATH_TO_OUTPUT_DIR"
else
  OUTDIR="$(pwd)"
fi

mkdir -p "$OUTDIR"

# Keep decrypted intermediate in TMPDIR, final .sql in OUTDIR (PWD by default)
DECRYPTED="$TMPDIR/backup.decrypted"

# Derive a reasonable final filename from the backup file name
orig_base=$(basename -- "$PATH_TO_BACKUP_FILE")
name_no_gpg=${orig_base%.gpg}
name_no_gz=${name_no_gpg%.gz}
if [[ "$name_no_gz" == *.sql ]]; then
  final_name="$name_no_gz"
else
  final_name="${name_no_gz}.sql"
fi
FINAL_SQL="$OUTDIR/$final_name"
# If file exists, append timestamp to avoid accidental overwrite
if [[ -e "$FINAL_SQL" ]]; then
  ts=$(date +%Y%m%d%H%M%S)
  FINAL_SQL="$OUTDIR/${name_no_gz}.${ts}.sql"
  echo "Notice: output file already existed; writing to $FINAL_SQL"
fi

echo "Decrypting: $PATH_TO_BACKUP_FILE"
# Decrypt to a temporary file. gpg will prompt for passphrase if needed (user must be present)
if ! gpg --batch --yes --decrypt --output "$DECRYPTED" "$PATH_TO_BACKUP_FILE"; then
  echo "gpg decryption failed" >&2
  exit 5
fi

# Detect if the decrypted file is gzip compressed
if file --brief --mime-type "$DECRYPTED" | grep -q gzip; then
  echo "Detected gzip compressed payload; decompressing to: $FINAL_SQL"
  if ! gunzip -c "$DECRYPTED" > "$FINAL_SQL"; then
    echo "gunzip failed" >&2
    exit 6
  fi
else
  # Not gzip: assume plain SQL or other plain text
  echo "Writing decrypted payload to: $FINAL_SQL"
  cp "$DECRYPTED" "$FINAL_SQL"
fi

echo "Unpacked SQL available at: $FINAL_SQL"

# Show a short preview
echo
echo "--- File preview (first 80 lines) ---"
head -n 80 "$FINAL_SQL" || true
echo "--- end preview ---"

echo
if [[ "$KEEP" = true ]]; then
  echo "Temporary files (including GNUPGHOME) retained under: $TMPDIR"
  echo "Final SQL file retained at: $FINAL_SQL"
else
  echo "Temporary files (excluding final SQL) were stored under: $TMPDIR (removed on exit)"
  echo "Final SQL file is at: $FINAL_SQL"
fi

# Print final path so callers can copy it if they used --keep or scripting
echo "$FINAL_SQL"
