#!/usr/bin/env bash
# Post-deploy pe Listara (Linux): migrări DB, cache Laravel, sync date referință.

set -euo pipefail

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

PHP_BINARY="${PHP_BINARY:-php}"
MYSQL_BIN="${MYSQL_BIN:-mysql}"
MYSQLDUMP_BIN="${MYSQLDUMP_BIN:-mysqldump}"

remote_artisan() {
  local artisan_cmd="$1"
  log "Remote artisan: ${artisan_cmd}"
  # Același user ca PHP-FPM (www-data) — cache file trebuie citibil la request-uri web.
  ssh_cmd "cd '${DEPLOY_PATH}' && sudo -u www-data ${PHP_BINARY} artisan ${artisan_cmd}"
}

run_remote_migrations() {
  if [[ "${RUN_REMOTE_MIGRATIONS:-true}" != "true" ]]; then
    log "Skipping remote migrations (RUN_REMOTE_MIGRATIONS=false)"
    return 0
  fi

  if [[ "${REMOTE_DB_BACKUP_BEFORE_MIGRATE:-true}" == "true" ]]; then
    log "Backing up production database before migrate..."
    local stamp backup_file
    stamp="$(date +%Y%m%d-%H%M%S)"
    backup_file="${DEPLOY_PATH}/${BACKUP_DIR}/db-before-migrate-${stamp}.sql"
    ssh_cmd "
      mkdir -p '${DEPLOY_PATH}/${BACKUP_DIR}' &&
      ${MYSQLDUMP_BIN} -h '${REMOTE_DB_HOST}' -P '${REMOTE_DB_PORT}' -u '${REMOTE_DB_USERNAME}' ${REMOTE_DB_PASSWORD:+-p'${REMOTE_DB_PASSWORD}'} '${REMOTE_DB_DATABASE}' > '${backup_file}' &&
      echo 'DB backup: ${backup_file}'
    " || warn "DB backup failed — continuing with migrate"
  fi

  remote_artisan "migrate --force"
  log "Remote migrations finished"
}

run_remote_cache_clear() {
  if [[ "${RUN_REMOTE_CACHE_CLEAR:-true}" != "true" ]]; then
    return 0
  fi
  log "Laravel optimize + warm application cache (layout/homepage)..."
  ssh_cmd "
    cd '${DEPLOY_PATH}' &&
    chown -R www-data:www-data storage bootstrap/cache 2>/dev/null || true &&
    chmod -R 775 storage bootstrap/cache 2>/dev/null || true
  "
  remote_artisan "optimize:clear"
  remote_artisan "config:cache" || true
  remote_artisan "route:cache" || true
  remote_artisan "view:cache" || true
  remote_artisan "cache:warm" || warn "cache:warm failed (non-fatal)"
  remote_artisan "cache:diagnostics" || warn "cache:diagnostics failed (non-fatal)"
}

run_cdn_static_sync() {
  if [[ "${RUN_CDN_STATIC_SYNC:-true}" != "true" ]]; then
    log "Skipping CDN static asset sync (RUN_CDN_STATIC_SYNC=false)"
    return 0
  fi

  if [[ "${DEPLOY_CDN_SYNC_APPLY:-false}" == "true" ]]; then
    log "Syncing CSS/JS to CDN/S3 (apply — uploads / Cloudflare purge)..."
    remote_artisan "cdn:sync-static-assets" || warn "CDN static sync failed"
  else
    log "Syncing CSS/JS to CDN/S3 (dry-run; set DEPLOY_CDN_SYNC_APPLY=true to upload/purge)..."
    remote_artisan "cdn:sync-static-assets -n" || warn "CDN static sync failed"
  fi
}

write_remote_deploy_marker() {
  local stamp commit branch marker
  stamp="$(date -u +%Y-%m-%dT%H:%M:%SZ)"
  commit="$(git -C "${PROJECT_ROOT}" rev-parse --short HEAD 2>/dev/null || echo 'unknown')"
  branch="$(git -C "${PROJECT_ROOT}" rev-parse --abbrev-ref HEAD 2>/dev/null || echo 'unknown')"
  marker="${DEPLOY_PATH}/public/deploy-version.txt"

  log "Writing deploy marker: public/deploy-version.txt"
  ssh_cmd "
    cd '${DEPLOY_PATH}' &&
    printf 'deployed_at=%s\ngit_commit=%s\ngit_branch=%s\ndeployed_from=%s\n' \
      '${stamp}' '${commit}' '${branch}' '$(hostname)' > public/deploy-version.txt
  "
}

verify_remote_deploy() {
  load_config
  log "Verifying production deploy at ${DEPLOY_PATH}"

  ssh_cmd "
    cd '${DEPLOY_PATH}' &&
    echo '--- deploy-version.txt ---' &&
    if [[ -f public/deploy-version.txt ]]; then cat public/deploy-version.txt; else echo 'MISSING: run deploy'; fi &&
    if [[ -f Modules/Category/Http/Requests/ChildCategoryRequest.php ]]; then echo 'OK ChildCategoryRequest.php'; else echo 'MISSING ChildCategoryRequest.php'; fi
  "

  if [[ "${RUN_REMOTE_MIGRATIONS:-true}" == "true" ]]; then
    log "Pending migrations (should be empty):"
    remote_artisan "migrate:status" | tail -15 || true
  fi

  if [[ "${RUN_REMOTE_CACHE_CLEAR:-true}" == "true" ]]; then
    log "Cache diagnostics (layout/homepage should be HIT after deploy):"
    remote_artisan "cache:diagnostics" 2>&1 | grep -E 'CACHE_DRIVER|Redis|HIT|MISS|Probe' || true
  fi
}

load_local_db_config() {
  local env_file="${PROJECT_ROOT}/.env"
  [[ -f "${env_file}" ]] || die "Missing .env for local database export"

  LOCAL_DB_HOST="$(grep -E '^DB_HOST=' "${env_file}" | cut -d= -f2- | tr -d "\"'" || echo '127.0.0.1')"
  LOCAL_DB_PORT="$(grep -E '^DB_PORT=' "${env_file}" | cut -d= -f2- | tr -d "\"'" || echo '3306')"
  LOCAL_DB_DATABASE="$(grep -E '^DB_DATABASE=' "${env_file}" | cut -d= -f2- | tr -d "\"'" || true)"
  LOCAL_DB_USERNAME="$(grep -E '^DB_USERNAME=' "${env_file}" | cut -d= -f2- | tr -d "\"'" || echo 'root')"
  LOCAL_DB_PASSWORD="$(grep -E '^DB_PASSWORD=' "${env_file}" | cut -d= -f2- | tr -d "\"'" || true)"
  : "${LOCAL_DB_DATABASE:?DB_DATABASE not set in .env}"
}

run_sync_reference_data() {
  if [[ "${DB_SYNC_REFERENCE_DATA:-false}" != "true" ]]; then
    log "Skipping reference data sync (DB_SYNC_REFERENCE_DATA=false)"
    return 0
  fi

  [[ -n "${DB_SYNC_TABLES:-}" ]] || die "Set DB_SYNC_TABLES in deploy.conf"

  load_local_db_config

  local dump_bin="${LOCAL_MYSQLDUMP_BIN:-/opt/lampp/bin/mysqldump}"
  if [[ ! -x "${dump_bin}" ]]; then
    dump_bin="$(command -v mysqldump || true)"
  fi
  if [[ -z "${dump_bin}" ]]; then
    warn "mysqldump not found — skip reference DB sync (set LOCAL_MYSQLDUMP_BIN in deploy.conf)"
    return 0
  fi

  local sql_file="${DEPLOY_DIR}/backups/reference-data-sync.sql"
  mkdir -p "${DEPLOY_DIR}/backups"

  local -a tables=()
  local IFS=','
  read -ra tables <<< "${DB_SYNC_TABLES}"
  for i in "${!tables[@]}"; do
    tables[$i]="$(echo "${tables[$i]}" | xargs)"
  done

  log "Exporting reference tables from local DB: ${DB_SYNC_TABLES}"
  local -a dump_args=(
    -h"${LOCAL_DB_HOST}" -P"${LOCAL_DB_PORT}" -u"${LOCAL_DB_USERNAME}"
    --no-create-info --skip-triggers --complete-insert --replace
    "${LOCAL_DB_DATABASE}"
    "${tables[@]}"
  )
  if [[ -n "${LOCAL_DB_PASSWORD}" ]]; then
    dump_args=(-p"${LOCAL_DB_PASSWORD}" "${dump_args[@]}")
  fi
  "${dump_bin}" "${dump_args[@]}" > "${sql_file}"

  {
    echo "SET FOREIGN_KEY_CHECKS=0;"
    cat "${sql_file}"
    echo "SET FOREIGN_KEY_CHECKS=1;"
  } > "${sql_file}.wrapped"
  mv "${sql_file}.wrapped" "${sql_file}"

  log "Importing reference data on Listara..."
  local remote_mysql="${MYSQL_BIN} -h ${REMOTE_DB_HOST} -P ${REMOTE_DB_PORT} -u ${REMOTE_DB_USERNAME}"
  if [[ -n "${REMOTE_DB_PASSWORD}" ]]; then
    remote_mysql+=" -p${REMOTE_DB_PASSWORD}"
  fi
  remote_mysql+=" ${REMOTE_DB_DATABASE}"

  cat "${sql_file}" | ssh_cmd "${remote_mysql}"

  cp "${sql_file}" "${DEPLOY_DIR}/backups/reference-data-sync-last.sql"
  log "Reference data sync finished"
}

run_all_remote_tasks() {
  load_config
  run_remote_migrations
  run_sync_reference_data

  if [[ -n "${REMOTE_POST_DEPLOY:-}" ]]; then
    log "Running REMOTE_POST_DEPLOY (permissions, nginx)..."
    ssh_cmd "${REMOTE_POST_DEPLOY}"
  fi

  log "Applying Listara performance patches (survives rsync)..."
  ssh_cmd "bash /opt/apps/scripts/apply-listara-performance.sh" || warn "apply-listara-performance failed"

  run_remote_cache_clear
  run_cdn_static_sync
  write_remote_deploy_marker
  verify_remote_deploy
}

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
  case "${1:-all}" in
    migrate) load_config && run_remote_migrations ;;
    media-sync) load_config && run_reference_media_push ;;
    db-sync) load_config && run_sync_reference_data ;;
    cache)   load_config && run_remote_cache_clear && write_remote_deploy_marker ;;
    cdn-sync) load_config && run_cdn_static_sync ;;
    verify)  verify_remote_deploy ;;
    all|*)   run_all_remote_tasks ;;
  esac
fi
