#!/usr/bin/env bash
# deploy/deploy.sh — One-time setup.
# Run once per project or re-run after config changes.
# Usage: bash deploy/deploy.sh [--skip-preflight]
set -euo pipefail

source "$(dirname "$0")/_lib.sh"

SKIP_PREFLIGHT=false
[[ "${1:-}" == "--skip-preflight" ]] && SKIP_PREFLIGHT=true

# ─────────────────────────────────────────────────────────────────
# Preflight
# ─────────────────────────────────────────────────────────────────
preflight() {
    section "Preflight checks"

    [[ -f "${VENV_PATH}/bin/activate" ]] \
        || die "Virtualenv not found: ${VENV_PATH}\n  Set PYTHON_VERSION in config.env and create the app in cPanel first."

    [[ -d "${APP_DIR}" ]] \
        || die "App directory not found: ${APP_DIR}"

    [[ -f "${APP_DIR}/main.py" ]] \
        || die "main.py not found in ${APP_DIR}"

    source "${VENV_PATH}/bin/activate"
    python -c "import fastapi, uvicorn" 2>/dev/null \
        || die "fastapi or uvicorn missing in virtualenv.\n  Run: pip install fastapi uvicorn gunicorn"

    success "Preflight passed"
}

# ─────────────────────────────────────────────────────────────────
# Install
# ─────────────────────────────────────────────────────────────────
install_packages() {
    section "Installing packages"
    source "${VENV_PATH}/bin/activate"
    pip install --quiet --upgrade supervisor gunicorn uvicorn
    success "supervisor, gunicorn, uvicorn installed"
}

create_dirs() {
    section "Creating directories"
    mkdir -p "${SUPERVISOR_DIR}/conf.d" "${SUPERVISOR_DIR}/logs" "${LOG_DIR}"
    success "Directories ready"
}

# ─────────────────────────────────────────────────────────────────
# Config files
# ─────────────────────────────────────────────────────────────────
write_supervisord_conf() {
    section "Writing supervisord.conf"
    cat > "${SUPERVISOR_DIR}/supervisord.conf" <<EOF
[unix_http_server]
file=${SUPERVISOR_DIR}/supervisor.sock
chmod=0700

[supervisord]
logfile=${SUPERVISOR_DIR}/logs/supervisord.log
logfile_maxbytes=20MB
logfile_backups=5
loglevel=info
pidfile=${SUPERVISOR_DIR}/supervisord.pid
nodaemon=false
minfds=1024
minprocs=200

[rpcinterface:supervisor]
supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface

[supervisorctl]
serverurl=unix://${SUPERVISOR_DIR}/supervisor.sock

[include]
files = ${SUPERVISOR_DIR}/conf.d/*.conf
EOF
    success "supervisord.conf written"
}

write_app_conf() {
    section "Writing app supervisor config"
    cat > "${SUPERVISOR_DIR}/conf.d/${APP_NAME}.conf" <<EOF
[program:${APP_NAME}]
command=${GUNICORN} main:app -c ${GUNICORN_CONF}
directory=${APP_DIR}
user=$(whoami)
autostart=true
autorestart=true
startretries=999999
stopwaitsecs=10
stopasgroup=true
killasgroup=true
redirect_stderr=false
stdout_logfile=${LOG_DIR}/app.log
stdout_logfile_maxbytes=20MB
stdout_logfile_backups=5
stderr_logfile=${LOG_DIR}/app.error.log
stderr_logfile_maxbytes=10MB
stderr_logfile_backups=3
environment=PATH="${VENV_BIN}:%(ENV_PATH)s",PYTHONUNBUFFERED="1"
EOF
    success "App config written → ${SUPERVISOR_DIR}/conf.d/${APP_NAME}.conf"
}

write_gunicorn_conf() {
    section "Writing gunicorn.conf.py"
    cat > "${GUNICORN_CONF}" <<EOF
# deploy/gunicorn.conf.py — Generated by deploy.sh. Regenerate via deploy.sh.
import multiprocessing

bind             = "0.0.0.0:${PORT}"
workers          = ${RESOLVED_WORKERS}
worker_class     = "${WORKER_CLASS}"
worker_connections = 1000
timeout          = ${TIMEOUT}
keepalive        = ${KEEPALIVE}
max_requests     = ${MAX_REQUESTS}
max_requests_jitter = ${MAX_REQUESTS_JITTER}
graceful_timeout = 30
preload_app      = True   # Load once before forking — saves RAM

# Logging
accesslog  = "${LOG_DIR}/access.log"
errorlog   = "${LOG_DIR}/error.log"
loglevel   = "info"
access_log_format = (
    '%(h)s %(l)s %(u)s %(t)s "%(r)s" %(s)s %(b)s "%(f)s" "%(a)s" %(D)sµs'
)

# Process
proc_name = "${APP_NAME}"
EOF
    success "gunicorn.conf.py written (${RESOLVED_WORKERS} workers, port ${PORT})"
}

# ─────────────────────────────────────────────────────────────────
# Cron — auto-start after reboot
# ─────────────────────────────────────────────────────────────────
setup_cron() {
    section "Cron auto-start"
    local job="@reboot sleep 30 && ${VENV_BIN}/supervisord -c ${SUPERVISOR_DIR}/supervisord.conf"

    if crontab -l 2>/dev/null | grep -qF "supervisord -c ${SUPERVISOR_DIR}"; then
        warn "Cron job already present — skipping"
    else
        (crontab -l 2>/dev/null; echo "$job") | crontab -
        success "Cron job added (@reboot)"
    fi
}

# ─────────────────────────────────────────────────────────────────
# Health endpoint hint
# ─────────────────────────────────────────────────────────────────
check_health_endpoint() {
    section "Health endpoint"
    if grep -qE "@app\.(get|route).*${HEALTH_PATH}" "${APP_DIR}/main.py" 2>/dev/null; then
        success "Health endpoint found (${HEALTH_PATH})"
    else
        warn "No health endpoint detected at ${HEALTH_PATH}"
        echo "  Add to main.py:"
        echo ""
        echo -e "  ${Y}@app.get(\"${HEALTH_PATH}\")"
        echo -e "  async def health():"
        echo -e "      return {\"status\": \"ok\"}${N}"
        echo ""
    fi
}

# ─────────────────────────────────────────────────────────────────
# Start
# ─────────────────────────────────────────────────────────────────
start_app() {
    section "Starting services"
    source "${VENV_PATH}/bin/activate"
    ensure_supervisor
    $SUPERVISORCTL reread
    $SUPERVISORCTL update
    $SUPERVISORCTL start "${APP_NAME}" 2>/dev/null || $SUPERVISORCTL restart "${APP_NAME}"
    sleep 2
    $SUPERVISORCTL status "${APP_NAME}"
}

# ─────────────────────────────────────────────────────────────────
# Main
# ─────────────────────────────────────────────────────────────────
main() {
    hr
    echo -e "${W}  FastAPI → Gunicorn + Supervisor deploy${N}"
    echo -e "  ${C}${DOMAIN} : port ${PORT}${N}"
    hr

    $SKIP_PREFLIGHT || preflight
    install_packages
    create_dirs
    write_supervisord_conf
    write_app_conf
    write_gunicorn_conf
    check_health_endpoint
    setup_cron
    start_app

    hr
    success "DEPLOYMENT COMPLETE"
    hr
    echo ""
    info "Manage:  bash deploy/control.sh <start|stop|restart|status|logs|health>"
    info "Release: bash deploy/release.sh"
    info "CI/CD:   bash deploy/ci.sh"
    echo ""
}

main
