#!/usr/bin/env bash
set -Eeuo pipefail

PROJECT_DIR="/home/snyt/public_html/SubDomain/Catalog"
INCLUDE_ORPHANS=false
DRY_RUN=false
SKIP_CHECKS=false

usage() {
  cat <<'EOF'
SNYT Catalog safe cleanup

Usage:
  ./cleanup_catalog_backups.sh [options]

Options:
  --project PATH       Laravel project path
  --include-orphans    Also quarantine reviewed, unreferenced legacy files
  --dry-run            Show what would move without changing anything
  --skip-checks        Skip PHP syntax and Artisan checks
  -h, --help           Show this help

Nothing is permanently deleted. Files are moved to a timestamped quarantine
directory under ~/catalog-cleanup-quarantine/.
EOF
}

while [[ $# -gt 0 ]]; do
  case "$1" in
    --project)
      [[ $# -ge 2 ]] || { echo "ERROR: --project requires a path." >&2; exit 1; }
      PROJECT_DIR="$2"
      shift 2
      ;;
    --include-orphans)
      INCLUDE_ORPHANS=true
      shift
      ;;
    --dry-run)
      DRY_RUN=true
      shift
      ;;
    --skip-checks)
      SKIP_CHECKS=true
      shift
      ;;
    -h|--help)
      usage
      exit 0
      ;;
    *)
      echo "ERROR: Unknown option: $1" >&2
      usage
      exit 1
      ;;
  esac
done

PROJECT_DIR="${PROJECT_DIR/#\~/$HOME}"
PROJECT_DIR="$(cd "$PROJECT_DIR" 2>/dev/null && pwd)" || {
  echo "ERROR: Project directory not found: $PROJECT_DIR" >&2
  exit 1
}

if [[ ! -f "$PROJECT_DIR/artisan" || ! -f "$PROJECT_DIR/composer.json" ]]; then
  echo "ERROR: This does not look like the Laravel Catalog project:" >&2
  echo "$PROJECT_DIR" >&2
  exit 1
fi

TIMESTAMP="$(date '+%Y%m%d_%H%M%S')"
QUARANTINE_ROOT="${HOME}/catalog-cleanup-quarantine"
QUARANTINE="${QUARANTINE_ROOT}/${TIMESTAMP}"
MANIFEST="${QUARANTINE}/MOVED_FILES.txt"

if [[ "$DRY_RUN" == false ]]; then
  mkdir -p "$QUARANTINE"
  : > "$MANIFEST"
fi

MOVED_COUNT=0
MOVED_BYTES=0

human_bytes() {
  local bytes="$1"
  if command -v numfmt >/dev/null 2>&1; then
    numfmt --to=iec-i --suffix=B "$bytes"
  else
    echo "${bytes} bytes"
  fi
}

file_size() {
  local file="$1"
  if stat -c '%s' "$file" >/dev/null 2>&1; then
    stat -c '%s' "$file"
  else
    stat -f '%z' "$file"
  fi
}

path_size() {
  local src="$1"
  if [[ -f "$src" || -L "$src" ]]; then
    file_size "$src"
  elif [[ -d "$src" ]]; then
    find "$src" -type f -print0 2>/dev/null |
      while IFS= read -r -d '' f; do file_size "$f"; done |
      awk '{sum += $1} END {print sum + 0}'
  else
    echo 0
  fi
}

move_path() {
  local src="$1"

  if [[ ! -e "$src" && ! -L "$src" ]]; then
    return 0
  fi

  local rel="${src#"$PROJECT_DIR"/}"
  local bytes
  bytes="$(path_size "$src")"

  if [[ "$DRY_RUN" == true ]]; then
    echo "Would move: $rel ($(human_bytes "$bytes"))"
  else
    local dst="$QUARANTINE/$rel"
    mkdir -p "$(dirname "$dst")"
    mv "$src" "$dst"
    printf '%s\n' "$rel" >> "$MANIFEST"
    echo "Moved: $rel ($(human_bytes "$bytes"))"
  fi

  MOVED_COUNT=$((MOVED_COUNT + 1))
  MOVED_BYTES=$((MOVED_BYTES + bytes))
}

echo
echo "=================================================="
echo " SNYT CATALOG SAFE CLEANUP"
echo "=================================================="
echo "Project: $PROJECT_DIR"
if [[ "$DRY_RUN" == true ]]; then
  echo "Mode:    DRY RUN"
else
  echo "Backup:  $QUARANTINE"
fi
echo

SEARCH_DIRS=()
for rel in app routes resources database config; do
  [[ -d "$PROJECT_DIR/$rel" ]] && SEARCH_DIRS+=("$PROJECT_DIR/$rel")
done

echo "1) Historical source snapshots and disabled copies"
while IFS= read -r -d '' file; do
  move_path "$file"
done < <(
  find "${SEARCH_DIRS[@]}" -type f \
    \( \
      -name '*.before-*' -o \
      -name '*.bak-*' -o \
      -name '*.bak' -o \
      -name '*.backup' -o \
      -name '*.old' -o \
      -name '*.orig' -o \
      -name '*~' -o \
      -name '*.disabled' \
    \) \
    -print0
)

echo
echo "2) Local SQLite database check"
SQLITE_FILE="$PROJECT_DIR/database/database.sqlite"
DB_CONNECTION=""

if [[ -f "$PROJECT_DIR/.env" ]]; then
  DB_CONNECTION="$(
    grep -m1 -E '^[[:space:]]*DB_CONNECTION=' "$PROJECT_DIR/.env" 2>/dev/null |
      cut -d= -f2- |
      tr -d '\r' |
      sed -E 's/[[:space:]]+#.*$//; s/^[[:space:]]+//; s/[[:space:]]+$//; s/^["'\'']//; s/["'\'']$//'
  )"
fi

if [[ -f "$SQLITE_FILE" ]]; then
  if [[ -n "$DB_CONNECTION" && "$DB_CONNECTION" != "sqlite" ]]; then
    echo "Production DB_CONNECTION is '$DB_CONNECTION'; SQLite is not active."
    move_path "$SQLITE_FILE"
  elif [[ "$DB_CONNECTION" == "sqlite" ]]; then
    echo "Keeping database/database.sqlite because DB_CONNECTION=sqlite."
  else
    echo "Keeping database/database.sqlite because DB_CONNECTION could not be verified."
  fi
else
  echo "No database/database.sqlite file found."
fi

if [[ "$INCLUDE_ORPHANS" == true ]]; then
  echo
  echo "3) Reviewed legacy/orphan candidates"
  move_path "$PROJECT_DIR/resources/views/welcome.blade.php"
  move_path "$PROJECT_DIR/resources/views/dashboard/index.blade.php"
  move_path "$PROJECT_DIR/resources/views/dashboard/salesman.blade.php"
  move_path "$PROJECT_DIR/app/Http/Controllers/Api/MobileController.php"
  move_path "$PROJECT_DIR/app/Models/MobileAccessToken.php"
  move_path "$PROJECT_DIR/app/Services/CatalogCoverGenerator.php"
else
  echo
  echo "3) Legacy/orphan candidates were left untouched."
  echo "   Use --include-orphans after the default cleanup is verified."
fi

if [[ "$DRY_RUN" == false ]]; then
  GITIGNORE="$PROJECT_DIR/.gitignore"
  MARKER="# SNYT local snapshots and generated backup files"

  touch "$GITIGNORE"

  if ! grep -Fq "$MARKER" "$GITIGNORE"; then
    cat >> "$GITIGNORE" <<'EOF'

# SNYT local snapshots and generated backup files
*.before-*
*.bak-*
*.bak
*.backup
*.old
*.orig
*.disabled
*~
database/*.sqlite*
/catalog-source-*.tar.gz
/catalog-source-clean-*.tar.gz
/catalog-full-*.tar.gz
EOF
    echo
    echo "Updated: .gitignore"
  fi

  cat > "$QUARANTINE/RESTORE_INSTRUCTIONS.txt" <<EOF
SNYT Catalog cleanup quarantine
Created: $(date)
Original project: $PROJECT_DIR

No files were permanently deleted.

Moved paths are listed in:
$MANIFEST

To restore one item, move it from this quarantine directory back to the same
relative path inside the Laravel project.
EOF
fi

echo
echo "=================================================="
echo " CLEANUP SUMMARY"
echo "=================================================="
echo "Entries: $MOVED_COUNT"
echo "Size:    $(human_bytes "$MOVED_BYTES")"
if [[ "$DRY_RUN" == false ]]; then
  echo "Stored:  $QUARANTINE"
fi

if [[ "$DRY_RUN" == true || "$SKIP_CHECKS" == true ]]; then
  exit 0
fi

echo
echo "=================================================="
echo " VERIFYING ACTIVE PHP FILES"
echo "=================================================="

PHP_FAILURES=0
PHP_COUNT=0
CHECK_DIRS=()

for rel in app routes config database/migrations database/seeders; do
  [[ -d "$PROJECT_DIR/$rel" ]] && CHECK_DIRS+=("$PROJECT_DIR/$rel")
done

while IFS= read -r -d '' file; do
  PHP_COUNT=$((PHP_COUNT + 1))
  if ! php -l "$file" >/dev/null 2>&1; then
    echo "Syntax failure: ${file#"$PROJECT_DIR"/}"
    php -l "$file" || true
    PHP_FAILURES=$((PHP_FAILURES + 1))
  fi
done < <(
  find "${CHECK_DIRS[@]}" -type f -name '*.php' \
    ! -name '*.before-*' \
    ! -name '*.bak-*' \
    ! -name '*.disabled' \
    -print0
)

echo "PHP files checked: $PHP_COUNT"
echo "Syntax failures:   $PHP_FAILURES"

ARTISAN_ABOUT="skipped"
ARTISAN_ROUTES="skipped"

if [[ -f "$PROJECT_DIR/vendor/autoload.php" ]]; then
  echo
  echo "Running non-destructive Laravel boot checks..."
  set +e
  (
    cd "$PROJECT_DIR"
    php artisan about >/dev/null
  )
  ABOUT_STATUS=$?

  (
    cd "$PROJECT_DIR"
    php artisan route:list >/dev/null
  )
  ROUTES_STATUS=$?
  set -e

  [[ $ABOUT_STATUS -eq 0 ]] && ARTISAN_ABOUT="passed" || ARTISAN_ABOUT="failed ($ABOUT_STATUS)"
  [[ $ROUTES_STATUS -eq 0 ]] && ARTISAN_ROUTES="passed" || ARTISAN_ROUTES="failed ($ROUTES_STATUS)"
fi

echo "artisan about:      $ARTISAN_ABOUT"
echo "artisan route:list: $ARTISAN_ROUTES"

if [[ $PHP_FAILURES -ne 0 ]]; then
  echo
  echo "WARNING: PHP syntax failures were found. Restore affected files before deployment."
  exit 2
fi

echo
echo "Cleanup and verification completed successfully."
