#!/bin/bash
# =============================================================================
# XinfinityGroup — cPanel FTP deployment script
# -----------------------------------------------------------------------------
# What this does (run once locally, it handles everything for you):
#   1. Preflight: pip-free local sanity (syntax compile, django checks,
#      pending-migration check).
#   2. collectstatic locally (production settings) so /staticfiles/ is fresh.
#   3. Mirrors the project to your cPanel folder /public_html/MX over FTP
#      (connection info is read from .vscode/sftp.json — single source of truth,
#      no password is ever duplicated or stored here).
#   4. Uploads only CHANGED files (size / mtime / missing), so re-runs are fast.
#
# Usage:
#   ./deploy.sh                 normal deploy
#   ./deploy.sh --dry-run       preview what would be uploaded (no network writes)
#   ./deploy.sh --yes-db        also upload your LOCAL db.sqlite3 (replaces live)
#   ./deploy.sh --prune         delete remote files that no longer exist locally
#   ./deploy.sh --htaccess      ALSO upload your local .htaccess (server copy wins otherwise)
#   ./deploy.sh --force         ignore size/mtime checks, upload every managed file
#   ./deploy.sh --skip-static   do not re-run collectstatic
# =============================================================================

set -euo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$ROOT"

PY="${PYTHON:-$ROOT/venv/bin/python}"
DRY_RUN=0
WITH_DB=0
PRUNE=0
HTACCESS=0
FORCE=0
SKIP_STATIC=0
YES_DB=0

for arg in "$@"; do
    case "$arg" in
        --dry-run)      DRY_RUN=1 ;;
        --with-db)      WITH_DB=1; YES_DB=1 ;;
        --yes-db)       YES_DB=1 ;;
        --prune)        PRUNE=1 ;;
        --htaccess)     HTACCESS=1 ;;
        --force)        FORCE=1 ;;
        --skip-static)  SKIP_STATIC=1 ;;
        *) echo "Unknown option: $arg"; exit 2 ;;
    esac
done

log()  { printf '\033[1;36m[deploy]\033[0m %s\n' "$*"; }
warn() { printf '\033[1;33m[deploy!]\033[0m %s\n' "$*"; }
die()  { printf '\033[1;31m[deploy X]\033[0m %s\n' "$*" >&2; exit 1; }

log "Project root: $ROOT"

# --- 0. Preconditions --------------------------------------------------------
[ -x "$PY" ] || die "venv python not found at $PY — run: python3 -m venv venv && venv/bin/pip install -r requirements.txt"
[ -f .vscode/sftp.json ] || die "Missing .vscode/sftp.json (deploy credentials)."
[ -f manage.py ]         || die "manage.py not found — deploy.sh must run from the project root."

log "Using python: $PY"

# --- 1. Local sanity checks ---------------------------------------------------
log "Compiling python (syntax)…"
"$PY" -m compileall -q cms backend >/dev/null 2>&1 || die "compileall found syntax errors."

log "Django system checks…"
DJANGO_SETTINGS_MODULE=backend.settings "$PY" manage.py check >/dev/null

# --- 2. Pending migrations check ----------------------------------------------
# We must never ship code whose DB schema isn't ready. sqlite migrations live
# in the DB file, so check the LOCAL db is migrated; the live DB is handled by
# the --yes-db / deploy_remote.sh path below.
if [ "$DRY_RUN" = 0 ]; then
    if DJANGO_SETTINGS_MODULE=backend.settings "$PY" manage.py migrate --check >/tmp/deploy_migrate_check.txt 2>&1; then
        log "All local migrations applied."
    else
        warn "Local DB has un-applied migrations. Run locally first:"
        warn "  $PY manage.py migrate"
        warn "Then re-run ./deploy.sh (or use --yes-db to push the migrated DB)."
        exit 1
    fi
fi

# --- 3. collectstatic ----------------------------------------------------------
if [ "$SKIP_STATIC" = 1 ]; then
    log "Skipping collectstatic (--skip-static)."
elif [ "$DRY_RUN" = 0 ]; then
    log "Running collectstatic (production settings)…"
    DJANGO_SETTINGS_MODULE=backend.settings "$PY" manage.py collectstatic --noinput --verbosity 0
else
    log "Dry-run: skipping collectstatic."
fi

# --- 4. db.sqlite3 -----------------------------------------------------------------
# The live database is NEVER replaced during a normal deploy. If you ever want
# to push your local DB, run: ./deploy.sh --with-db
[ "$WITH_DB" = 1 ] && YES_DB=1

# --- 5. FTP mirror -------------------------------------------------------------
EXTRA_ARGS=()
[ "$DRY_RUN" = 0 ] || EXTRA_ARGS+=(--dry-run)
[ "$PRUNE" = 0 ]   || EXTRA_ARGS+=(--prune)
[ "$HTACCESS" = 0 ]|| EXTRA_ARGS+=(--htaccess)
[ "$FORCE" = 0 ]   || EXTRA_ARGS+=(--force)
[ "$YES_DB" = 1 ]  || EXTRA_ARGS+=(--no-db)

log "Syncing to FTP ($( [ "$DRY_RUN" = 0 ] && echo upload || echo dry-run ))…"
"$PY" deploy_ftp.py "${EXTRA_ARGS[@]}"

# --- 6. Finish -----------------------------------------------------------------
if [ "$DRY_RUN" = 1 ]; then
    log "Dry-run complete — nothing was written remotely."
    exit 0
fi

log "Deploy finished."
echo
echo "======================================================================"
echo " ACTION REQUIRED on this deploy (new DB tables were added):"
echo "  1. Open cPanel Terminal (or SSH)"
echo "  2. Paste exactly:"
echo
echo "     cd public_html/MX && bash deploy_remote.sh"
echo
echo " This installs requirements, runs 'migrate' on the LIVE db, runs"
echo " collectstatic, and restarts Passenger. Without it the new schema"
echo " won't exist yet and the site may show errors on contact pages."
echo "======================================================================"