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

set -euo pipefail

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

remote_artisan() {
  local artisan_cmd="$1"
  log "Remote artisan: ${artisan_cmd}"
  # -d output_buffering=0 so progress bar streams over SSH during long commands
  ssh_cmd "cd /d ${DEPLOY_PATH_WIN} && ${PHP_BINARY_WIN} -d output_buffering=0 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_WIN}/${BACKUP_DIR}/db-before-migrate-${stamp}.sql"
  ssh_cmd "powershell -NoProfile -Command \"
    \\\$mysql = '${MYSQL_BIN_WIN}/mysql.exe';
    \\\$dump = '${MYSQL_BIN_WIN}/mysqldump.exe';
    \\\$out = '${backup_file}';
    New-Item -ItemType Directory -Force -Path (Split-Path \\\$out) | Out-Null;
    & \\\$dump -h ${REMOTE_DB_HOST} -P ${REMOTE_DB_PORT} -u ${REMOTE_DB_USERNAME} ${REMOTE_DB_PASSWORD:+-p${REMOTE_DB_PASSWORD}} ${REMOTE_DB_DATABASE} | Set-Content -Encoding UTF8 \\\$out;
    Write-Output ('DB backup: ' + \\\$out)
  \"" || 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..."
  remote_artisan "optimize:clear"
  remote_artisan "config:cache" || true
  remote_artisan "route:cache" || true
  remote_artisan "view:cache" || true
  remote_artisan "cache:warm" || true
  remote_artisan "cache:diagnostics" || true
}

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

  log "Syncing CSS/JS to CDN/S3 (only changed files; first run may take several minutes)..."
  if [[ "${DEPLOY_CDN_SYNC_APPLY:-false}" == "true" ]]; then
    log "Syncing CSS/JS to CDN/S3 (apply)..."
    remote_artisan "cdn:sync-static-assets" || warn "CDN static sync failed (check storage settings and logs)"
  else
    remote_artisan "cdn:sync-static-assets -n" || warn "CDN static sync failed (check storage settings and logs)"
  fi
}

write_remote_deploy_marker() {
  local stamp commit branch marker_win
  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_win="${DEPLOY_PATH_WIN}/public/deploy-version.txt"

  log "Writing deploy marker on production: public/deploy-version.txt"
  ssh_cmd "cd /d ${DEPLOY_PATH_WIN} && (echo deployed_at=${stamp}>public\\deploy-version.txt) && (echo git_commit=${commit}>>public\\deploy-version.txt) && (echo git_branch=${branch}>>public\\deploy-version.txt) && (echo deployed_from=$(hostname)>>public\\deploy-version.txt)"
}

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

  ssh_cmd "cd /d ${DEPLOY_PATH_WIN} && echo --- deploy-version.txt --- && if exist public\\deploy-version.txt (type public\\deploy-version.txt) else (echo MISSING: run ./deploy.sh) && if exist Modules\\Category\\Http\\Requests\\ChildCategoryRequest.php (echo OK ChildCategoryRequest.php) else (echo MISSING ChildCategoryRequest.php) && if exist Modules\\Listing\\Resources\\views\\frontend\\partials\\listing-location-fields.blade.php (echo OK listing-location-fields.blade.php) else (echo MISSING listing-location-fields.blade.php)"

  if [[ "${RUN_REMOTE_MIGRATIONS:-true}" == "true" ]]; then
    log "Pending migrations (should be empty):"
    remote_artisan "migrate:status" | tail -15 || 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 (comma-separated table names)"

  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 [[ -n "${dump_bin}" ]]; then
    :
  else
    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"

  # shellcheck disable=SC2206
  local 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}"

  log "Importing reference data on production (merge into: ${DB_SYNC_TABLES})..."
  {
    echo "SET FOREIGN_KEY_CHECKS=0;"
    cat "${sql_file}"
    echo "SET FOREIGN_KEY_CHECKS=1;"
  } > "${sql_file}.wrapped"
  mv "${sql_file}.wrapped" "${sql_file}"

  local mysql_bin="${MYSQL_BIN_WIN}/mysql.exe"
  local -a ssh_mysql_opts=(
    -i "${SSH_KEY_PATH}"
    -p "${DEPLOY_PORT}"
    -o BatchMode=yes
    -o PasswordAuthentication=no
    -o IdentitiesOnly=yes
  )
  if [[ -f "${SSH_KNOWN_HOSTS}" ]]; then
    ssh_mysql_opts+=(-o "UserKnownHostsFile=${SSH_KNOWN_HOSTS}")
  fi

  local remote_mysql_cmd="\"${mysql_bin}\" -h ${REMOTE_DB_HOST} -P ${REMOTE_DB_PORT} -u ${REMOTE_DB_USERNAME}"
  if [[ -n "${REMOTE_DB_PASSWORD}" ]]; then
    remote_mysql_cmd+=" -p${REMOTE_DB_PASSWORD}"
  fi
  remote_mysql_cmd+=" ${REMOTE_DB_DATABASE}"

  # Stream SQL over SSH (avoids scp path issues on Windows OpenSSH)
  cat "${sql_file}" | ssh "${ssh_mysql_opts[@]}" \
    "${DEPLOY_USER}@${DEPLOY_HOST}" "${remote_mysql_cmd}"

  cp "${sql_file}" "${DEPLOY_DIR}/backups/reference-data-sync-last.sql"
  log "Reference data sync finished (backup: deploy/backups/reference-data-sync-last.sql)"
}

run_all_remote_tasks() {
  load_config
  if [[ "${DEPLOY_PLATFORM:-windows}" == "linux" ]]; then
    exec "${SCRIPT_DIR}/remote-tasks-linux.sh" all
  fi
  run_remote_migrations
  run_sync_reference_data
  run_remote_cache_clear
  run_cdn_static_sync
  write_remote_deploy_marker

  if [[ -n "${REMOTE_POST_DEPLOY:-}" ]]; then
    log "Running custom REMOTE_POST_DEPLOY..."
    ssh_cmd "${REMOTE_POST_DEPLOY}"
  fi

  verify_remote_deploy
}

if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
  case "${1:-all}" in
    migrate)
      load_config
      [[ "${DEPLOY_PLATFORM:-windows}" == "linux" ]] && exec "${SCRIPT_DIR}/remote-tasks-linux.sh" migrate
      run_remote_migrations
      ;;
    media-sync)
      load_config
      [[ "${DEPLOY_PLATFORM:-windows}" == "linux" ]] && exec "${SCRIPT_DIR}/remote-tasks-linux.sh" media-sync
      die "REFERENCE_MEDIA_SYNC is only supported on Linux (Listara)"
      ;;
    db-sync)
      load_config
      [[ "${DEPLOY_PLATFORM:-windows}" == "linux" ]] && exec "${SCRIPT_DIR}/remote-tasks-linux.sh" db-sync
      run_sync_reference_data
      ;;
    cache)
      load_config
      [[ "${DEPLOY_PLATFORM:-windows}" == "linux" ]] && exec "${SCRIPT_DIR}/remote-tasks-linux.sh" cache
      run_remote_cache_clear && write_remote_deploy_marker
      ;;
    cdn-sync)
      load_config
      [[ "${DEPLOY_PLATFORM:-windows}" == "linux" ]] && exec "${SCRIPT_DIR}/remote-tasks-linux.sh" cdn-sync
      run_cdn_static_sync
      ;;
    verify)
      load_config
      [[ "${DEPLOY_PLATFORM:-windows}" == "linux" ]] && exec "${SCRIPT_DIR}/remote-tasks-linux.sh" verify
      verify_remote_deploy
      ;;
    all|*)   run_all_remote_tasks ;;
  esac
fi
