#!/usr/bin/env bash
# site/clone -- copy a managed site to a new domain
#
# Files are copied with ownership preserved, the database is dumped and
# re-imported (never moved), and URLs are rewritten only when wp-cli is present.
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
ui_header "$(t site_m_clone)" "$(t site_clone_sub)"

if [ "$(nv_site_count)" -eq 0 ]; then ui_info "$(t site_none)"; exit 0; fi

printf '  %s (%s): ' "$(t site_clone_source)" "$(nv_site_list | paste -sd' ' -)"
read -r src || exit 130
src=$(nv_lower "$(nv_trim "$src")")
nv_site_exists "$src" || { ui_err "$(t site_not_registered)"; exit 2; }

printf '  %s: ' "$(t site_clone_target)"
read -r dst || exit 130
dst=$(nv_lower "$(nv_trim "$dst")")
nv_valid_domain "$dst" || { ui_err "$(t site_bad_domain "$dst")"; exit 2; }
nv_site_exists "$dst" && { ui_err "$(t site_already_exists "$dst")"; exit 2; }
[ -e "$(site_vhost_path "$dst")" ] && { ui_err "$(t site_conflict "$dst")"; exit 2; }

src_root=$(nv_site_get "$src" root_path)
src_db=$(nv_site_get "$src" db_name "")
[ -d "$src_root" ] || { ui_err "$(t site_clone_no_root "$src_root")"; exit 1; }

ui_blank
ui_kv "$(t site_clone_source)" "$src"
ui_kv "$(t site_clone_target)" "$dst"
ui_confirm "$(t site_clone_confirm)" n || { ui_info "$(t pf_cancelled)"; exit 0; }

nv_lock_acquire "site:$dst" 10 || { nv_fail 6199 "$(t lock_busy "$dst")"; exit 1; }

phpv=$(nv_site_get "$src" php_version "$NV_SITE_PHP_VERSION")
dst_root=$(site_domain_root "$dst")

# --- account and directories ---------------------------------------------
ui_step "$(t site_step_user)"
site_ensure_user "$dst" || { nv_fail 3101 "$(t site_fail_user)"; exit 1; }
site_ensure_dirs "$dst"

# --- database -------------------------------------------------------------
ui_step "$(t site_step_db)"
db_row=$(site_ensure_db "$dst") || exit 1
IFS=$'\t' read -r dst_db dst_user dst_pass <<<"$db_row"

if [ -n "$src_db" ] && db_available; then
    ui_step "$(t site_clone_copy_db)"
    tmp=$(nv_tmpfile)
    pass=$(nv_secret db_root_password)
    if [ -n "$pass" ]; then
        mysqldump --protocol=socket -u root -p"$pass" --single-transaction "$src_db" >"$tmp" 2>/dev/null
    else
        mysqldump --protocol=socket -u root --single-transaction "$src_db" >"$tmp" 2>/dev/null
    fi
    if [ -s "$tmp" ]; then
        mariadb --protocol=socket -u root "$dst_db" <"$tmp" 2>/dev/null \
            || ui_warn "$(t site_clone_import_failed)"
        ui_ok "$(t site_clone_db_ok)"
    else
        ui_warn "$(t site_clone_dump_failed)"
    fi
    rm -f "$tmp"
fi

# --- files ----------------------------------------------------------------
ui_step "$(t site_clone_copy_files)"
rsync -a --delete "$src_root/" "$dst_root/" || {
    nv_fail 3301 "$(t site_clone_files_failed)"; exit 1; }
chown -R "$dst:$dst" "$dst_root"

# --- application level rewrite -------------------------------------------
if [ -f "$dst_root/wp-config.php" ] && [ -x /usr/local/bin/wp ]; then
    ui_step "$(t site_clone_rewrite_url)"
    sudo -u "$dst" /usr/local/bin/wp --path="$dst_root" config set DB_NAME "$dst_db" --quiet 2>/dev/null || true
    sudo -u "$dst" /usr/local/bin/wp --path="$dst_root" config set DB_USER "$dst_user" --quiet 2>/dev/null || true
    sudo -u "$dst" /usr/local/bin/wp --path="$dst_root" config set DB_PASSWORD "$dst_pass" --quiet 2>/dev/null || true
    sudo -u "$dst" /usr/local/bin/wp --path="$dst_root" search-replace "//$src" "//$dst" --all-tables --quiet 2>/dev/null \
        && ui_ok "$(t site_clone_url_ok)" || ui_warn "$(t site_clone_url_manual)"
fi

# --- web server -----------------------------------------------------------
ui_step "$(t site_step_pool)"
site_write_pool "$dst" "$phpv"
ui_step "$(t site_step_vhost)"
site_apply_vhost "$dst" || { nv_fail 3201 "$(t site_fail_nginx)"; exit 1; }

# --- registry -------------------------------------------------------------
nv_site_create "$dst"
nv_site_set "$dst" php_version "$phpv"
nv_site_set "$dst" root_path   "$dst_root"
nv_site_set "$dst" web_user    "$(site_username "$dst")"
nv_site_set "$dst" db_name     "$dst_db"
nv_site_set "$dst" db_user     "$dst_user"
nv_site_set "$dst" cache_redis "$(nv_site_get "$src" cache_redis 0)"

site_reload "$phpv"
nv_trace site-clone "$src -> $dst"
nv_lock_release "site:$dst"

ui_blank
ui_ok "$(t site_clone_done "$src" "$dst")"
exit 0
