#!/usr/bin/env bash
# Incremental Dropbox → persistent ~/DyzineFrame-Staging (hourly / manual).
# Sets ~/DyzineFrame/run/staging-pending when staging differs from live deploy tree.
#
#   QUIET=1 bash stage_from_dropbox.sh
#   DRY_RUN=1 bash stage_from_dropbox.sh

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"

PATHS="${ROOT}/dropbox_paths.sh"
FILTER_FILE="${ROOT}/dyzineframe.rclone-filter"
DRY_RUN="${DRY_RUN:-0}"
VERBOSE="${VERBOSE:-1}"
if [[ "${QUIET:-0}" == "1" ]]; then
  VERBOSE=0
fi

if [[ -f "${PATHS}" ]]; then
  # shellcheck source=dropbox_paths.sh
  source "${PATHS}"
fi

load_rclone_remote() {
  local candidate env_file
  for candidate in \
    "${HOME}/EtherGold/sync/rclone.env" \
    "${HOME}/EtherGold/4-Board Test Fixture/sync/rclone.env"; do
    if [[ ! -f "${candidate}" ]]; then
      continue
    fi
    env_file="${candidate}"
    if grep -q $'\r' "${env_file}" 2>/dev/null; then
      sed -i 's/\r$//' "${env_file}" 2>/dev/null || true
    fi
    # shellcheck source=/dev/null
    source "${env_file}"
    if [[ -n "${RCLONE_REMOTE:-}" ]]; then
      echo "RCLONE_REMOTE from ${env_file}"
      return 0
    fi
  done
  RCLONE_REMOTE="${RCLONE_REMOTE:-dyzine-dropbox}"
  echo "RCLONE_REMOTE default: ${RCLONE_REMOTE}"
}

load_rclone_remote

if [[ ! -f "${FILTER_FILE}" ]]; then
  echo "Missing ${FILTER_FILE}" >&2
  exit 1
fi

if ! command -v rclone >/dev/null 2>&1; then
  echo "rclone not found. Run: bash ~/EtherGold/sync/setup_rclone.sh" >&2
  exit 1
fi

OTA_CHANNEL="${OTA_CHANNEL:-field}"
if [[ "${OTA_CHANNEL}" == "dev" ]]; then
  DEPLOY_REMOTE="${DROPBOX_DYZINEFRAME_DEPLOY_DEV:-SGVI/dev/DyzineFrame}"
else
  DEPLOY_REMOTE="${DROPBOX_DYZINEFRAME_DEPLOY:-${DROPBOX_DYZINEFRAME_DEPLOY_CANON:?missing DROPBOX_DYZINEFRAME_DEPLOY_CANON}}"
fi
REMOTE_PATH="${RCLONE_REMOTE}:${DEPLOY_REMOTE}"

RCLONE_ARGS=(
  --filter-from "${FILTER_FILE}"
  --create-empty-src-dirs
  --stats 5s
  --stats-one-line
)

if [[ "${VERBOSE}" == "1" ]]; then
  RCLONE_ARGS+=(-v --progress)
else
  RCLONE_ARGS+=(--log-level "${RCLONE_LOG_LEVEL:-NOTICE}")
fi

if [[ "${DRY_RUN}" == "1" ]]; then
  RCLONE_ARGS+=(--dry-run)
  echo "DRY RUN — staging only, no writes."
  echo ""
fi

echo "Remote:  ${REMOTE_PATH}  (OTA_CHANNEL=${OTA_CHANNEL})"
echo "Stage:   ${DYZINEFRAME_STAGING} (persistent)"
echo "Live:    ${DYZINEFRAME_ROOT}"
echo ""

mkdir -p "${DYZINEFRAME_STAGING}" "${DYZINEFRAME_ROOT}/run" "${DYZINEFRAME_ROOT}/sync"

_rclone_boot=()
if [[ "${DRY_RUN}" == "1" ]]; then
  _rclone_boot+=(--dry-run)
fi

echo "Bootstrap: refresh sync/*.sh from remote"
rclone copy "${REMOTE_PATH}/sync/" "${ROOT}/" "${_rclone_boot[@]}" -v

echo "Stage: incremental copy from Dropbox"
rclone copy "${REMOTE_PATH}" "${DYZINEFRAME_STAGING}" "${RCLONE_ARGS[@]}"

if [[ "${DRY_RUN}" == "1" ]]; then
  echo "Dry run complete."
  exit 0
fi

normalize_dyzineframe_shell_scripts "${DYZINEFRAME_STAGING}"
normalize_dyzineframe_shell_scripts "${ROOT}"

ota_apply_rollback_directive \
  "${DYZINEFRAME_ROOT}" \
  "${DYZINEFRAME_STAGING}" \
  "${DYZINEFRAME_ROLLBACK}" \
  "${ROOT}/rollback_live.sh"

sv="$(ota_read_version "${DYZINEFRAME_STAGING}")"
lv="$(ota_live_version "${DYZINEFRAME_ROOT}")"
if ota_version_is_older "${sv}" "${lv}"; then
  echo "staging ${sv} older than live ${lv} — park Staging → Rollback (not pending)"
  mkdir -p "${DYZINEFRAME_ROLLBACK}"
  deploy_rsync_merge "${DYZINEFRAME_STAGING}" "${DYZINEFRAME_ROLLBACK}"
  {
    echo "parked_at=$(date -Is)"
    echo "parked_version=${sv}"
    echo "live_version=${lv}"
    echo "reason=staging_older_than_live"
  } > "${DYZINEFRAME_ROLLBACK}/.rollback-meta"
  rm -f "${DYZINEFRAME_PENDING_FLAG}"
  if [[ -x "${ROOT}/log_offload.sh" ]]; then
    bash "${ROOT}/log_offload.sh" || echo "WARN: log_offload failed (non-fatal)"
  fi
  echo "stage_from_dropbox ok"
  exit 0
fi

stamp_rc=0
ota_staging_differs_by_stamp "${DYZINEFRAME_STAGING}" "${DYZINEFRAME_ROOT}" || stamp_rc=$?
pending=0
if [[ "${stamp_rc}" -eq 0 ]]; then
  pending=1
elif [[ "${stamp_rc}" -eq 2 ]] && deploy_tree_has_diff "${DYZINEFRAME_STAGING}" "${DYZINEFRAME_ROOT}"; then
  pending=1
fi

if [[ "${pending}" -eq 1 ]]; then
  ota_write_pending_flag "${DYZINEFRAME_PENDING_FLAG}" "${DYZINEFRAME_STAGING}" "${DYZINEFRAME_ROOT}"
  echo "staging-pending: set ($(tr '\n' ' ' < "${DYZINEFRAME_PENDING_FLAG}"))"
else
  echo "staging-pending: clear (VERSION/MANIFEST match live)"
  rm -f "${DYZINEFRAME_PENDING_FLAG}"
fi

if [[ -x "${ROOT}/log_offload.sh" ]]; then
  bash "${ROOT}/log_offload.sh" || echo "WARN: log_offload failed (non-fatal)"
fi

echo "stage_from_dropbox ok"
