#!/usr/bin/env bash
# site/wp-create -- provision a WordPress site
#
# Declarative: every step ensures a state, so re-running repairs instead of
# duplicating. The registry is written last, and only after validation passes.
set -o pipefail
SELF=$(readlink -f "${BASH_SOURCE[0]}")
NV_BASE=$(cd "$(dirname "$SELF")/../../.." && pwd)
export NV_BASE
# shellcheck source=/dev/null
. "$NV_BASE/lib/core/bootstrap.sh"

nv_require_root || exit 1

PHP_V=$(nv_conf php_version "${NV_SITE_PHP_VERSION:-8.3}")
ui_header "$(t site_m_create)" "$(t site_create_sub)"

# --- input ----------------------------------------------------------------
default_domain=""
PLAIN=0
if [ $# -ge 1 ]; then default_domain=$1; shift; fi
# --plain: vhost, pool and database, but no WordPress. Used by the installer
# when the operator asked for an empty site.
[ "${1:-}" = "--plain" ] && PLAIN=1

if [ -n "$default_domain" ]; then
    domain=$default_domain
else
    printf '  %s: ' "$(t site_prompt_domain)"
    read -r domain || exit 130
fi
domain=$(nv_lower "$(nv_trim "$domain")")
domain=${domain#http://}; domain=${domain#https://}; domain=${domain%%/*}

if ! nv_valid_domain "$domain"; then
    ui_err "$(t site_bad_domain "$domain")"
    exit 2
fi

if nv_site_exists "$domain"; then
    ui_warn "$(t site_already_exists "$domain")"
    exit 0
fi

if [ -e "/etc/nginx/sites-available/$domain.conf" ] || [ -d "/home/$domain" ]; then
    ui_err "$(t site_conflict "$domain")"
    exit 2
fi

printf '  %s (%s): ' "$(t site_prompt_email)" "$(t site_email_use)"
read -r email || exit 130
email=$(nv_trim "$email")

# --- lock -----------------------------------------------------------------
nv_lock_acquire "site:$domain" 10 || { nv_fail 6199 "$(t lock_busy "$domain")"; exit 1; }

ROOT=$(site_domain_root "$domain")
VHOST=$(site_vhost_path "$domain")
POOL=$(site_pool_path "$domain" "$PHP_V")
db_name=$(site_slug "$domain")
db_user="u_${db_name#wp_}"

ui_blank
ui_section "$(t site_plan)"
ui_kv "$(t col_domain)"   "$domain"
ui_kv "$(t col_php)"      "$PHP_V"
ui_kv "$(t site_root)"    "$ROOT"
ui_kv "$(t site_db)"      "$db_name"
ui_kv "$(t site_db_user)" "$db_user"
ui_blank

# --- 1. system account and directories ------------------------------------
ui_step "$(t site_step_user)"
site_ensure_user "$domain" || { nv_fail 3101 "$(t site_fail_user)"; exit 1; }
WEB_USER=$(site_web_user "$domain")
site_ensure_dirs "$domain"

# --- 2. database ----------------------------------------------------------
ui_step "$(t site_step_db)"
db_available || { nv_fail 3101 "$(t site_fail_db_down)"; exit 1; }
db_row=$(site_ensure_db "$domain" "$db_name" "$db_user") || exit 1
IFS=$'\t' read -r db_name db_user db_pass <<<"$db_row"

# --- 3. dedicated php-fpm pool -------------------------------------------
ui_step "$(t site_step_pool)"
site_write_pool "$domain" "$PHP_V"

# --- 4. nginx vhost -------------------------------------------------------
ui_step "$(t site_step_vhost)"
site_apply_vhost "$domain" || { nv_fail 3201 "$(t site_fail_nginx)"; exit 1; }

# --- 5. application -------------------------------------------------------
ui_step "$(t site_step_wp)"
if [ "$PLAIN" = "1" ]; then
    # an empty site still needs something to serve, otherwise every request is
    # a 403 and the operator thinks the panel broke the server
    if [ ! -f "$ROOT/index.html" ] && [ ! -f "$ROOT/index.php" ]; then
        cat >"$ROOT/index.html" <<HTML
<!doctype html>
<html lang="vi"><head><meta charset="utf-8"><title>$domain</title></head>
<body><h1>$domain</h1><p>$(t site_plain_ready)</p></body></html>
HTML
    fi
    chown -R "$(site_web_user "$domain"):$(site_web_user "$domain")" "$ROOT" 2>/dev/null || true
    ui_ok "$(t site_plain_ok)"
    WP_CLI=/nonexistent
else
WP_CLI=/usr/local/bin/wp
if [ ! -x "$WP_CLI" ]; then
    tmp=$(nv_tmpfile)
    if curl -fsSL --max-time 120 -o "$tmp" https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar 2>/dev/null; then
        install -m 0755 "$tmp" "$WP_CLI"
    fi
    rm -f "$tmp"
fi

if [ -x "$WP_CLI" ]; then
    sudo -u "$WEB_USER" "$WP_CLI" core download --path="$ROOT" --quiet 2>/dev/null || true
    if [ -f "$ROOT/wp-config.php" ] || sudo -u "$WEB_USER" "$WP_CLI" config create \
            --path="$ROOT" --dbname="$db_name" --dbuser="$db_user" \
            --dbpass="$db_pass" --dbhost=localhost --quiet 2>/dev/null; then
        ui_ok "$(t site_wp_ready)"
    else
        ui_warn "$(t site_wp_partial)"
    fi
else
    ui_warn "$(t site_wp_nocli)"
fi

chown -R "$WEB_USER:$WEB_USER" "$ROOT"
fi

# --- 6. registry (last, only after success) -------------------------------
nv_site_create "$domain"
nv_site_set "$domain" php_version "$PHP_V"
nv_site_set "$domain" root_path   "$ROOT"
nv_site_set "$domain" web_user    "$WEB_USER"
nv_site_set "$domain" db_name     "$db_name"
nv_site_set "$domain" db_user     "$db_user"
[ -n "$email" ] && nv_site_set "$domain" ssl_email "$email"

svc_reload "$(php_fpm_service "$PHP_V")"
svc_reload nginx
nv_lock_release "site:$domain"

ui_blank
ui_ok "$(t site_created "$domain")"
ui_kv "$(t site_url)" "http://$domain"
[ -n "$email" ] && ui_info "$(t site_ssl_hint)"
ui_blank
exit 0
