#!/usr/bin/env bash
#
# MailBeez BeezUI deploy script
# Copies files from app_dev -> app with flexible excludes.
#
# Defaults resolve relative to this script's location (symlinks resolved).
# You can override with -s/--source and -d/--dest.
#
# Examples
#   Dry run (default):
#     ./deploy_app_dev_to_app.sh
#
#   Actually copy (no dry-run) and show progress:
#     ./deploy_app_dev_to_app.sh --execute -v
#
#   Copy only PHP and JS files, excluding node_modules and playground:
#     ./deploy_app_dev_to_app.sh --execute --only-php-js -e node_modules/ -e playground/
#
#   Use an exclude file (one pattern per line):
#     ./deploy_app_dev_to_app.sh --execute --exclude-file ./deploy.exclude
#
set -euo pipefail

# Ensure running with bash (do not invoke with 'sh')
if [ -z "${BASH_VERSION:-}" ]; then
  echo "This script requires bash. Please run it with: bash \"$0\" [args]" >&2
  exit 1
fi

# Determine script directory robustly (handles symlinks)
resolve_script_dir() {
  local src="${BASH_SOURCE[0]}"
  while [ -h "$src" ]; do
    local dir
    dir="$(cd -P "$(dirname "$src")" && pwd)"
    src="$(readlink "$src")"
    [[ $src != /* ]] && src="$dir/$src"
  done
  cd -P "$(dirname "$src")" >/dev/null 2>&1 && pwd
}

SCRIPT_DIR="$(resolve_script_dir)"

# Default paths relative to this script's directory
DEFAULT_SOURCE="$SCRIPT_DIR/catalog/mailhive/app_dev"
DEFAULT_DEST="$SCRIPT_DIR/catalog/mailhive/app"

SOURCE="$DEFAULT_SOURCE"
DEST="$DEFAULT_DEST"

DRY_RUN=1           # 1=dry-run, 0=execute
VERBOSE=0
QUIET=0
DO_DELETE=0         # 1=delete extraneous files in DEST
ONLY_PHP_JS=0       # 1=limit to *.php and *.js

EXCLUDES=(
  # Common heavy/irrelevant directories
  "node_modules/"
  "playground/"
  "var/"
  "scripts/"                        # don't deploy scripts themselves
  "tests/"                        # don't deploy scripts themselves
  # Tooling/IDE/local
  ".junie/"
  ".idea/"
  ".git/"
  ".gitignore"
  ".DS_Store"
  "/prompt.md"
  "/package.json"
  "/package-lock.json"
  "/composer.json"
  "/composer.lock"
  "/composer-lock.json"
  "/build.md"
  # App-specific build artifacts or large buckets
)

EXCLUDE_FILE=""

print_usage() {
  cat <<'USAGE'
MailBeez BeezUI deploy: app_dev -> app

Usage: deploy_app_dev_to_app.sh [options]

Options:
  -s, --source <path>        Source directory (default: catalog/mailhive/app_dev relative to this script)
  -d, --dest <path>          Destination directory (default: catalog/mailhive/app relative to this script)
  -n, --dry-run              Dry run (default). Show what would change.
      --execute              Perform the copy (disables dry-run)
  -v, --verbose              Verbose rsync output
  -q, --quiet                Quiet mode (less output)
      --delete               Delete files in DEST that no longer exist in SOURCE
      --only-php-js          Deploy only *.php and *.js files (and needed dirs)
  -e, --exclude <pattern>    Add an exclude pattern (can be used multiple times)
      --exclude-file <path>  File with exclude patterns (one per line)
  -h, --help                 Show this help

Notes:
- Exclude patterns are relative to the SOURCE root.
- To exclude a directory entirely, end with '/': e.g. 'node_modules/'
- When using --only-php-js, we include directories (*/), then *.php and *.js, and exclude everything else.
USAGE
}

# Parse args
while [[ $# -gt 0 ]]; do
  case "$1" in
    -s|--source)
      SOURCE="$2"; shift 2 ;;
    -d|--dest)
      DEST="$2"; shift 2 ;;
    -n|--dry-run)
      DRY_RUN=1; shift ;;
    --execute)
      DRY_RUN=0; shift ;;
    -v|--verbose)
      VERBOSE=1; shift ;;
    -q|--quiet)
      QUIET=1; shift ;;
    --delete)
      DO_DELETE=1; shift ;;
    --only-php-js)
      ONLY_PHP_JS=1; shift ;;
    -e|--exclude)
      EXCLUDES+=("$2"); shift 2 ;;
    --exclude-file)
      EXCLUDE_FILE="$2"; shift 2 ;;
    -h|--help)
      print_usage; exit 0 ;;
    *)
      echo "Unknown argument: $1" >&2
      print_usage
      exit 1 ;;
  esac
done

# Validate paths
if [[ ! -d "$SOURCE" ]]; then
  echo "Source directory does not exist: $SOURCE" >&2
  exit 2
fi

mkdir -p "$DEST"

# Build rsync options
RSYNC_OPTS=("-a")

# Human-friendly
if [[ $VERBOSE -eq 1 ]]; then
  RSYNC_OPTS+=("-v" "--progress" "--human-readable")
fi

if [[ $QUIET -eq 1 ]]; then
  RSYNC_OPTS+=("-q")
fi

if [[ $DRY_RUN -eq 1 ]]; then
  RSYNC_OPTS+=("-n")
fi

if [[ $DO_DELETE -eq 1 ]]; then
  RSYNC_OPTS+=("--delete" "--delete-excluded")
fi

# Include/exclude rules
FILTER_RULES=()

if [[ $ONLY_PHP_JS -eq 1 ]]; then
  # Traverse directories
  FILTER_RULES+=("--include=*/")
  # Include only php/js files
  FILTER_RULES+=("--include=*.php" "--include=*.PHP")
  FILTER_RULES+=("--include=*.js"  "--include=*.JS")
  # Everything else excluded by default
  FILTER_RULES+=("--exclude=*")
fi

# Apply default and user-specified excludes
for pat in "${EXCLUDES[@]}"; do
  FILTER_RULES+=("--exclude=$pat")
done

if [[ -n "$EXCLUDE_FILE" ]]; then
  if [[ ! -f "$EXCLUDE_FILE" ]]; then
    echo "Exclude file not found: $EXCLUDE_FILE" >&2
    exit 3
  fi
  FILTER_RULES+=("--exclude-from=$EXCLUDE_FILE")
fi

# Preview
echo "Deploying MailBeez BeezUI"
[[ $DRY_RUN -eq 1 ]] && echo "Mode      : DRY-RUN (no changes will be made)" || echo "Mode      : EXECUTE (files will be copied)"
[[ $VERBOSE -eq 1 ]] && echo "Verbosity : verbose" || echo "Verbosity : normal"
[[ $DO_DELETE -eq 1 ]] && echo "Delete    : enabled (dest files not in source will be removed)" || echo "Delete    : disabled"
[[ $ONLY_PHP_JS -eq 1 ]] && echo "Scope     : only *.php and *.js" || echo "Scope     : all files (minus excludes)"
echo "Source    : $SOURCE"
echo "Dest      : $DEST"

# Run rsync
# Trailing slashes ensure rsync copies the contents of SOURCE into DEST
set -x
rsync "${RSYNC_OPTS[@]}" "${FILTER_RULES[@]}" -- "$SOURCE/" "$DEST/"
set +x

echo
if [[ $DRY_RUN -eq 1 ]]; then
  echo "Dry-run complete. Re-run with --execute to perform the copy."
else
  echo "Deploy completed successfully."
fi
