#!/usr/bin/env bash
# onx-wp-staging-push — Staging ortamını production'a iter (rsync + DB + URL replace).
#
# Input (stdin JSON):
#   {
#     "staging_path":      "/home/onx_xxx/staging",
#     "production_path":   "/home/onx_xxx/public_html",
#     "staging_url":       "https://staging.site.com",
#     "production_url":    "https://site.com",
#     "staging_db":        "onx_xxx_wp10_staging",
#     "production_db":     "onx_xxx_wp10",
#     "username":          "onx_xxx",
#     "include_files":     true,
#     "include_db":        true,
#     "exclude_uploads":   true
#   }
#
# Output (stdout JSON):
#   {"success":true,"files_synced":N,"db_pushed":true,"duration_ms":N}
#
# Exit codes: 0=ok  1=invalid  2=preflight  3=exec-fail  4=rollback-ok  5=rollback-fail
#
# Deployed to: /usr/local/onoxsoft/bin/onx-wp-staging-push

set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=_lib/common.sh
source "${SCRIPT_DIR}/_lib/common.sh"

WP_CLI_BIN="${WP_CLI_BIN:-/usr/local/bin/wp}"

require_root
require_cmd rsync
require_cmd mysql
require_cmd mysqldump

onx_json_input

USERNAME="$(onx_json_field username)"
STAGING_PATH="$(onx_json_field staging_path)"
PRODUCTION_PATH="$(onx_json_field production_path)"
STAGING_URL="$(onx_json_field staging_url)"
PRODUCTION_URL="$(onx_json_field production_url)"
STAGING_DB="$(onx_json_field staging_db)"
PRODUCTION_DB="$(onx_json_field production_db)"
INCLUDE_FILES="$(onx_json_get_bool "$INPUT" include_files true)"
INCLUDE_DB="$(onx_json_get_bool "$INPUT" include_db true)"
EXCLUDE_UPLOADS="$(onx_json_get_bool "$INPUT" exclude_uploads true)"

[[ -z "$USERNAME"       ]] && onx_die 1 "username zorunlu"
[[ -z "$STAGING_PATH"   ]] && onx_die 1 "staging_path zorunlu"
[[ -z "$PRODUCTION_PATH" ]] && onx_die 1 "production_path zorunlu"

onx_validate_username "$USERNAME"
[[ -d "$STAGING_PATH" ]]   || onx_die 2 "staging_path mevcut değil: '${STAGING_PATH}'"
[[ -d "$PRODUCTION_PATH" ]] || onx_die 2 "production_path mevcut değil: '${PRODUCTION_PATH}'"

onx_log "staging-push: ${STAGING_PATH} → ${PRODUCTION_PATH} (user=${USERNAME})"

# Rollback: production DB yedeği (push öncesi alınmış olmalı, burada ekstra güvenlik)
BACKUP_FILE="/tmp/onx-prod-backup-${PRODUCTION_DB}-$(date +%s).sql"
onx_rollback_register "mysql '${PRODUCTION_DB}' < '${BACKUP_FILE}'"
onx_rollback_register "rm -f '${BACKUP_FILE}'"
trap 'onx_rollback_run' ERR

START_NS=$(date +%s%N)
FILES_COUNT=0
DB_PUSHED=false

# ─── Dosya senkronizasyonu ────────────────────────────────────────────────────
if [[ "$INCLUDE_FILES" == "true" ]]; then
    RSYNC_EXCLUDES=()
    [[ "$EXCLUDE_UPLOADS" == "true" ]] && RSYNC_EXCLUDES+=("--exclude=wp-content/uploads")
    RSYNC_EXCLUDES+=(
        "--exclude=wp-config.php"   # Production'daki wp-config.php korunur
        "--exclude=wp-content/cache"
        "--exclude=*.log"
    )

    mysqldump --single-transaction "$PRODUCTION_DB" > "$BACKUP_FILE" \
        || onx_die 3 "Production DB yedeklenemedi"

    rsync -a --delete \
        "${RSYNC_EXCLUDES[@]}" \
        "${STAGING_PATH}/" \
        "${PRODUCTION_PATH}/" \
        --chown="${USERNAME}:${USERNAME}"

    FILES_COUNT=$(find "$PRODUCTION_PATH" -type f 2>/dev/null | wc -l || echo 0)
fi

# ─── DB push ──────────────────────────────────────────────────────────────────
if [[ "$INCLUDE_DB" == "true" && -n "$STAGING_DB" && -n "$PRODUCTION_DB" ]]; then
    [[ "$STAGING_DB"    =~ ^onx_[a-z0-9]+_[a-z0-9_]+$ ]] || onx_die 1 "Geçersiz staging_db"
    [[ "$PRODUCTION_DB" =~ ^onx_[a-z0-9]+_[a-z0-9_]+$ ]] || onx_die 1 "Geçersiz production_db"

    STAGING_DUMP="/tmp/onx-staging-push-${STAGING_DB}-$(date +%s).sql"
    onx_rollback_register "rm -f '${STAGING_DUMP}'"

    # Staging DB dump
    mysqldump --single-transaction --routines --triggers "$STAGING_DB" > "$STAGING_DUMP" \
        || onx_die 3 "Staging mysqldump başarısız"

    # Production DB'yi temizle ve yükle
    mysql -e "DROP DATABASE IF EXISTS \`${PRODUCTION_DB}\`; CREATE DATABASE \`${PRODUCTION_DB}\` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;" \
        || onx_die 3 "Production DB reset başarısız"

    mysql "$PRODUCTION_DB" < "$STAGING_DUMP" \
        || onx_die 3 "Production DB import başarısız"

    rm -f "$STAGING_DUMP"

    # URL search-replace: staging URL → production URL
    if command -v "$WP_CLI_BIN" >/dev/null 2>&1 && [[ -f "${PRODUCTION_PATH}/wp-config.php" ]]; then
        sudo -u "$USERNAME" "$WP_CLI_BIN" \
            --path="$PRODUCTION_PATH" \
            --no-color \
            search-replace "$STAGING_URL" "$PRODUCTION_URL" \
            --all-tables || true

        # Production'ı indexlenebilir yap
        sudo -u "$USERNAME" "$WP_CLI_BIN" \
            --path="$PRODUCTION_PATH" \
            --no-color \
            option update blog_public 1 || true
    fi

    rm -f "$BACKUP_FILE"
    DB_PUSHED=true
fi

END_NS=$(date +%s%N)
DURATION_MS=$(( (END_NS - START_NS) / 1000000 ))

onx_log "staging-push done: files=${FILES_COUNT} db=${DB_PUSHED} duration_ms=${DURATION_MS}"

printf '{"success":true,"files_synced":%d,"db_pushed":%s,"duration_ms":%d}\n' \
    "$FILES_COUNT" "$DB_PUSHED" "$DURATION_MS"
