#!/usr/bin/env bash
# ──────────────────────────────────────────────────────────────────────────
# hdg — HestiaCP + Django + Gunicorn Global CLI
# ──────────────────────────────────────────────────────────────────────────
# A fast, global tool for deploying and managing Django on HestiaCP.
#
# Usage from ANYWHERE on your system:
#   hdg <domain> <user> [project]       # Quick deploy (auto-detects project)
#   hdg setup <domain> <user> [project] # Explicit deploy
#   hdg repair <domain> <user>          # Fix & migrate existing setup
#   hdg doctor <domain> <user>          # Run health checks
#   hdg status <domain>                 # Check service status
#   hdg update                          # Self-update to latest version
#   hdg install                         # Re-link global commands
#
# Prepared by: MohammadAmin Baranzehi — amin.baranzehi.com
# ──────────────────────────────────────────────────────────────────────────

set -euo pipefail

# ── Resolve real project directory even through symlinks ──────────────────
SOURCE="${BASH_SOURCE[0]}"
while [ -h "$SOURCE" ]; do
    DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
    SOURCE="$(readlink "$SOURCE")"
    [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
done
PROJECT_ROOT="$(cd -P "$(dirname "$SOURCE")" && pwd)"
CLI_PY="${PROJECT_ROOT}/cli.py"

# ── Colours ───────────────────────────────────────────────────────────────
RED='\033[0;91m'
GREEN='\033[0;92m'
YELLOW='\033[0;93m'
CYAN='\033[0;96m'
BOLD='\033[1m'
NC='\033[0m'

info()    { echo -e "  ${CYAN}[*]${NC} $*"; }
success() { echo -e "  ${GREEN}[+]${NC} $*"; }
warn()    { echo -e "  ${YELLOW}[!]${NC} $*"; }
error()   { echo -e "  ${RED}[-]${NC} $*"; }

# ── Self-installation to /usr/local/bin ───────────────────────────────────
install_global_links() {
    local bin_dir="/usr/local/bin"
    [ ! -d "$bin_dir" ] && return 0

    local links=("hdg" "v-django" "hestia-django" "add-gunicorn-service")
    local need_install=0

    for link in "${links[@]}"; do
        local target="${bin_dir}/${link}"
        if [ ! -L "$target" ] || [ "$(readlink -f "$target" 2>/dev/null)" != "${PROJECT_ROOT}/hdg" ]; then
            need_install=1
            break
        fi
    done

    if [ "$need_install" -eq 1 ]; then
        local SUDO=""
        [ "${EUID:-$(id -u)}" -ne 0 ] && command -v sudo &>/dev/null && SUDO="sudo"

        for link in "${links[@]}"; do
            $SUDO ln -sf "${PROJECT_ROOT}/hdg" "${bin_dir}/${link}" 2>/dev/null || true
        done
        $SUDO chmod +x "${PROJECT_ROOT}/hdg" 2>/dev/null || true

        if [ ! -f "${PROJECT_ROOT}/.installed" ]; then
            touch "${PROJECT_ROOT}/.installed" 2>/dev/null || true
            echo ""
            success "Installed globally as '${BOLD}hdg${NC}' (also '${BOLD}v-django${NC}')"
            info "You can now run '${BOLD}hdg <domain> <user>${NC}' from ANY directory!"
            echo ""
        fi
    fi
}

# ── Self-update command ───────────────────────────────────────────────────
self_update() {
    echo ""
    echo -e "${BOLD}Updating hdg (HestiaCP Django-Gunicorn Engine)...${NC}"

    if [ -d "${PROJECT_ROOT}/.git" ] && command -v git &>/dev/null; then
        info "Pulling latest changes from git repository..."
        git -C "$PROJECT_ROOT" checkout -- . 2>/dev/null || true
        git -C "$PROJECT_ROOT" pull --ff-only 2>/dev/null || {
            warn "git pull --ff-only failed, trying standard pull..."
            git -C "$PROJECT_ROOT" pull 2>/dev/null || {
                warn "Pull conflict detected, resetting to upstream branch..."
                git -C "$PROJECT_ROOT" reset --hard "@{u}" 2>/dev/null || warn "Could not pull git updates"
            }
        }
    else
        info "Git repository not detected, skipping git pull."
    fi

    local hestia_tpl_dir="/usr/local/hestia/data/templates/web/nginx"
    if [ -d "$hestia_tpl_dir" ]; then
        info "Updating NGINX templates in HestiaCP..."
        local SUDO=""
        [ "${EUID:-$(id -u)}" -ne 0 ] && command -v sudo &>/dev/null && SUDO="sudo"
        $SUDO cp -f "${PROJECT_ROOT}/templates/django-gunicorn.tpl" "$hestia_tpl_dir/" 2>/dev/null || true
        $SUDO cp -f "${PROJECT_ROOT}/templates/django-gunicorn.stpl" "$hestia_tpl_dir/" 2>/dev/null || true
        success "NGINX templates updated in ${hestia_tpl_dir}"
    fi

    install_global_links
    success "hdg is up to date and ready!"
    echo ""
    exit 0
}

# ── Handle self-install / update directly ─────────────────────────────────
case "${1:-}" in
    install|self-install)
        install_global_links
        success "Global installation complete! Run '${BOLD}hdg${NC}' from anywhere."
        exit 0
        ;;
    update|self-update)
        self_update
        ;;
esac

# ── Automatically install or update global symlink on run ────────────────
install_global_links 2>/dev/null || true

# ── Try Python engine first ──────────────────────────────────────────────
if command -v python3 &>/dev/null && [ -f "$CLI_PY" ]; then
    python3 "$CLI_PY" "$@"
    exit $?
fi

# ══════════════════════════════════════════════════════════════════════════
# Bash fallback (self-contained, for servers without full Python setup)
# ══════════════════════════════════════════════════════════════════════════

usage() {
    echo -e "${BOLD}hdg${NC} — HestiaCP + Django + Gunicorn CLI"
    echo ""
    echo "Usage:"
    echo "  hdg <domain> <user> [project]       # Auto-deploy"
    echo "  hdg repair <domain> <user>          # Fix existing deployment"
    echo "  hdg doctor <domain> <user>          # Check deployment health"
    echo "  hdg update                          # Self-update"
    echo ""
    echo "Examples:"
    echo "  hdg example.com admin myproject"
    echo "  hdg example.com admin               # auto-detects config/wsgi.py"
    echo "  hdg repair example.com admin"
    echo "  hdg update"
    exit 1
}

# ── Handle 'repair' ───────────────────────────────────────────────────────
if [ "${1:-}" = "repair" ]; then
    [ "$#" -lt 3 ] && usage
    DOMAIN="$2"
    USER="$3"
    SERVICE_NAME="gunicorn-${DOMAIN}"
    SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"

    if [ ! -f "$SERVICE_FILE" ]; then
        error "Service file not found: $SERVICE_FILE"
        exit 1
    fi

    info "Repairing deployment for: $DOMAIN"
    BACKUP="${SERVICE_FILE}.bak.$(date +%Y%m%d_%H%M%S)"
    cp "$SERVICE_FILE" "$BACKUP"
    success "Backed up to: $BACKUP"

    "$0" "$DOMAIN" "$USER"
    exit $?
fi

# ── Handle 'setup' explicit keyword ──────────────────────────────────────
if [ "${1:-}" = "setup" ]; then
    shift
fi

# ── Parse arguments ──────────────────────────────────────────────────────
[ "$#" -lt 2 ] && usage

DOMAIN="$1"
USER="$2"
PROJECT="${3:-}"

HOMEDIR="/home/$USER"
WEBDIR="$HOMEDIR/web/$DOMAIN/public_html"
SERVICE_NAME="gunicorn-${DOMAIN}"
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"

if [ ! -d "$WEBDIR" ]; then
    error "Domain directory not found: $WEBDIR"
    exit 1
fi

# ── Virtualenv detection ─────────────────────────────────────────────────
if [ -d "$WEBDIR/venv" ]; then
    VENV_BIN="$WEBDIR/venv/bin"
elif [ -d "$WEBDIR/.venv" ]; then
    VENV_BIN="$WEBDIR/.venv/bin"
elif [ -d "$HOMEDIR/.virtualenvs/$DOMAIN" ]; then
    VENV_BIN="$HOMEDIR/.virtualenvs/$DOMAIN/bin"
else
    error "Virtual environment not found in:"
    error "  $WEBDIR/venv"
    error "  $WEBDIR/.venv"
    error "  $HOMEDIR/.virtualenvs/$DOMAIN"
    exit 1
fi

if [ ! -f "$VENV_BIN/gunicorn" ]; then
    error "Gunicorn is not installed in the virtualenv ($VENV_BIN/gunicorn missing)."
    error "Install it: $VENV_BIN/pip install gunicorn"
    exit 1
fi

# ── WSGI auto-detection ──────────────────────────────────────────────────
WSGI_MODULE=""

if [ -n "$PROJECT" ] && [ -f "$WEBDIR/$PROJECT/wsgi.py" ]; then
    WSGI_MODULE="${PROJECT}.wsgi:application"
    info "WSGI module (specified): $WSGI_MODULE"
elif [ -f "$WEBDIR/config/wsgi.py" ]; then
    WSGI_MODULE="config.wsgi:application"
    info "WSGI module (detected modular): $WSGI_MODULE"
else
    DETECTED_WSGI=$(find "$WEBDIR" -maxdepth 3 -name "wsgi.py" \
                    -not -path "*/venv/*" \
                    -not -path "*/.venv/*" \
                    -not -path "*/site-packages/*" \
                    | head -n 1)

    if [ -n "$DETECTED_WSGI" ]; then
        REL_WSGI="${DETECTED_WSGI#$WEBDIR/}"
        MODULE_PATH="${REL_WSGI%/wsgi.py}"
        MODULE_DOT=$(echo "$MODULE_PATH" | tr '/' '.')

        if [ "$REL_WSGI" = "wsgi.py" ]; then
            WSGI_MODULE="wsgi:application"
        else
            WSGI_MODULE="${MODULE_DOT}.wsgi:application"
        fi
        info "WSGI module (auto-detected): $WSGI_MODULE"
    else
        error "Could not auto-detect wsgi.py in $WEBDIR"
        error "Please specify the project name: $0 $DOMAIN $USER <project_name>"
        exit 1
    fi
fi

# ── Environment & Workers ────────────────────────────────────────────────
ENV_FILE_LINE=""
if [ -f "$WEBDIR/.env" ]; then
    ENV_FILE_LINE="EnvironmentFile=$WEBDIR/.env"
    info "Environment file detected: $WEBDIR/.env"
fi

CPU_COUNT=$(nproc 2>/dev/null || echo 1)
WORKERS=$(( (2 * CPU_COUNT) + 1 ))
[ "$WORKERS" -gt 9 ] && WORKERS=9
SOCK_PATH="$WEBDIR/gunicorn.sock"

# ── Print summary ────────────────────────────────────────────────────────
echo ""
echo -e "${BOLD}Deployment Summary${NC}"
echo "  Domain    : $DOMAIN"
echo "  User      : $USER"
echo "  WSGI      : $WSGI_MODULE"
echo "  Workers   : $WORKERS"
echo "  Socket    : $SOCK_PATH"
echo "  Service   : $SERVICE_NAME"
echo ""

# ── Generate service file ────────────────────────────────────────────────
if [ -f "$SERVICE_FILE" ]; then
    BACKUP="${SERVICE_FILE}.bak.$(date +%Y%m%d_%H%M%S)"
    cp "$SERVICE_FILE" "$BACKUP"
    warn "Existing service backed up to: $BACKUP"
fi

cat <<EOF | sudo tee "$SERVICE_FILE" > /dev/null
# ──────────────────────────────────────────────────────────────────
# Gunicorn service for $DOMAIN
# Auto-generated by hdg (HestiaCP Django-Gunicorn Engine)
# ──────────────────────────────────────────────────────────────────
[Unit]
Description=Gunicorn instance for $DOMAIN (Django)
After=network.target

[Service]
User=$USER
Group=www-data
WorkingDirectory=$WEBDIR
Environment="PATH=$VENV_BIN:/usr/local/bin:/usr/bin"
Environment="PYTHONUNBUFFERED=1"
$ENV_FILE_LINE
ExecStart=$VENV_BIN/gunicorn \\
          --access-logfile - \\
          --error-logfile - \\
          --workers $WORKERS \\
          --threads 2 \\
          --worker-class=gthread \\
          --bind unix:$SOCK_PATH \\
          --umask 007 \\
          --log-level=info \\
          $WSGI_MODULE

Restart=always
RestartSec=3
ProtectSystem=full
PrivateTmp=true
NoNewPrivileges=true

[Install]
WantedBy=multi-user.target
EOF

success "Generated: $SERVICE_FILE"

# ── Fix database permissions ─────────────────────────────────────────────
if [ -f "$WEBDIR/db.sqlite3" ]; then
    sudo chown "$USER:www-data" "$WEBDIR/db.sqlite3"
    sudo chmod 664 "$WEBDIR/db.sqlite3"
    success "Fixed SQLite permissions on db.sqlite3"
fi

# ── Enable & start service ───────────────────────────────────────────────
sudo systemctl daemon-reload
sudo systemctl enable "$SERVICE_NAME"
sudo systemctl restart "$SERVICE_NAME"

sleep 1
if sudo systemctl is-active --quiet "$SERVICE_NAME"; then
    success "Service $SERVICE_NAME is running!"
else
    error "Service failed to start. Logs:"
    sudo journalctl -u "$SERVICE_NAME" -n 20 --no-pager
    exit 1
fi

echo ""
echo -e "${GREEN}${BOLD}Deployment completed successfully!${NC}"
