#!/usr/bin/env bash
# Promote persistent staging → live DyzineFrame (03:00 America/St_Thomas / boot / Update Now).
# Snapshots live deploy tree to ~/DyzineFrame-Rollback before merge.
#
#   bash promote_staging.sh
#   FORCE=1 bash promote_staging.sh
#   PROMOTE_RESTART=1 bash promote_staging.sh
#   CONFIRM_PROMOTE_HOLD=1 FORCE=1 bash promote_staging.sh   # operator override of rollback hold

if grep -q $'\r' "${BASH_SOURCE[0]}" 2>/dev/null; then
  sed -i 's/\r$//' "${BASH_SOURCE[0]}"
  exec bash "${BASH_SOURCE[0]}" "$@"
fi

set -euo pipefail

if [[ "$(id -un)" == root ]]; then
  echo "FATAL: do not run as root/sudo." >&2
  exit 1
fi

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=dyzineframe_paths.sh
source "${ROOT}/dyzineframe_paths.sh"
# shellcheck source=deploy_rsync.sh
source "${ROOT}/deploy_rsync.sh"
# shellcheck source=ota_lib.sh
source "${ROOT}/ota_lib.sh"

FORCE="${FORCE:-0}"
PROMOTE_RESTART="${PROMOTE_RESTART:-0}"
CONFIRM_PROMOTE_HOLD="${CONFIRM_PROMOTE_HOLD:-0}"

if [[ ! -d "${DYZINEFRAME_STAGING}" ]]; then
  echo "FATAL: missing staging dir ${DYZINEFRAME_STAGING}" >&2
  echo "  Run: bash ${ROOT}/stage_from_dropbox.sh" >&2
  exit 1
fi

if ota_promote_held "${DYZINEFRAME_ROOT}" "${DYZINEFRAME_STAGING}"; then
  if [[ "${CONFIRM_PROMOTE_HOLD}" != "1" ]]; then
    echo "promote_staging: hold — staging VERSION is the broken from_version. Skip."
    echo "  Operator override: CONFIRM_PROMOTE_HOLD=1 FORCE=1 bash promote_staging.sh"
    exit 2
  fi
  echo "promote_staging: operator confirmed hold override"
  ota_clear_promote_hold "${DYZINEFRAME_ROOT}"
fi

sv="$(ota_read_version "${DYZINEFRAME_STAGING}")"
lv="$(ota_live_version "${DYZINEFRAME_ROOT}")"
if ota_version_is_older "${sv}" "${lv}"; then
  if [[ "${CONFIRM_DOWNGRADE}" != "1" ]]; then
    echo "promote_staging: skip — staging ${sv} older than live ${lv} (LAN/workshop ahead of SGVI)."
    echo "  Staging was not applied. Park it as Rollback on the next stage_from_dropbox."
    echo "  Override: CONFIRM_DOWNGRADE=1 FORCE=1 bash promote_staging.sh"
    rm -f "${DYZINEFRAME_PENDING_FLAG}"
    exit 0
  fi
  echo "promote_staging: operator confirmed downgrade ${lv} -> ${sv}"
fi

if [[ "${FORCE}" != "1" ]] && [[ ! -f "${DYZINEFRAME_PENDING_FLAG}" ]]; then
  echo "promote_staging: nothing pending — skip"
  exit 0
fi

if ! deploy_tree_has_diff "${DYZINEFRAME_STAGING}" "${DYZINEFRAME_ROOT}"; then
  echo "promote_staging: staging matches live — clear flag and skip"
  rm -f "${DYZINEFRAME_PENDING_FLAG}"
  exit 0
fi

echo "=== promote_staging ==="
echo "Rollback snapshot: ${DYZINEFRAME_ROLLBACK}/"
echo "Live:              ${DYZINEFRAME_ROOT}/"
echo "From staging:      ${DYZINEFRAME_STAGING}/"
echo ""

mkdir -p "${DYZINEFRAME_ROLLBACK}" "${DYZINEFRAME_ROOT}/run"

echo "Saving live deploy tree → rollback"
deploy_rsync_merge "${DYZINEFRAME_ROOT}" "${DYZINEFRAME_ROLLBACK}"
{
  echo "saved_at=$(date -Is)"
  echo "saved_version=$(ota_read_version "${DYZINEFRAME_ROOT}")"
} > "${DYZINEFRAME_ROLLBACK}/.rollback-meta"
# Rollback snapshot VERSION.txt is the live tree we just copied.

echo "Promoting staging → live"
deploy_rsync_merge "${DYZINEFRAME_STAGING}" "${DYZINEFRAME_ROOT}"
normalize_dyzineframe_shell_scripts "${DYZINEFRAME_ROOT}"

if [[ -f "${ROOT}/pi_normalize.sh" ]]; then
  bash "${ROOT}/pi_normalize.sh"
fi

if [[ -f "${ROOT}/install_http_date_sync.sh" ]]; then
  bash "${ROOT}/install_http_date_sync.sh" || echo "WARN: HTTP date timer not installed (need sudo -n)" >&2
fi

rm -f "${DYZINEFRAME_PENDING_FLAG}"
{
  echo "promoted_at=$(date -Is)"
  echo "live_version=$(ota_read_version "${DYZINEFRAME_ROOT}")"
} > "${DYZINEFRAME_ROOT}/run/last-promote.txt"

echo ""
echo "promote_staging ok"
echo "Live version: $(ota_read_version "${DYZINEFRAME_ROOT}")"

if [[ "${PROMOTE_RESTART}" == "1" ]]; then
  echo "Restarting DyzineFrame child (supervisor stays up)..."
  ota_restart_dyzineframe "${DYZINEFRAME_ROOT}"
else
  echo "Restart from Pi desktop (or set PROMOTE_RESTART=1)."
fi
