#!/bin/bash
# Regression test: start.sh dashboard bundle sync step.
#
# Validates the auto-sync that runs before `docker run` in start.sh:
#   1. Bundles are coppied from /opt/dashcaddy/status/dist → /var/www/dashcaddy-status/dist
#   2. sw.js is copied to /var/www/dashcaddy-status/sw.js
#   3. index.html is copied to /var/www/dashcaddy-status/index.html
#   4. Missing source dir is handled gracefully (WARN, no exit)
#   5. Sync is idempotent — re-running doesn't clobber or duplicate

set -u
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
FAILURES=0

pass() { echo "  ✓ $1"; }
fail() { echo "  ✗ $1"; FAILURES=$((FAILURES + 1)); }

# --------------------------------------------------------------------------
# Extract just the sync block from start.sh. The first call to `docker run`
# marks the end of the sync section.
# --------------------------------------------------------------------------
extract_sync_block() {
  awk '
    /^# Sync the freshly-built dashboard bundle/ { capture=1 }
    /^docker run -d --restart unless-stopped/ { capture=0 }
    capture { print }
  ' "${SCRIPT_DIR}/../start.sh"
}

fresh_workdir() {
  local d; d="$(mktemp -d /tmp/dashcaddy-sync-test.XXXXXX)"
  mkdir -p "$d/src/dist"
  mkdir -p "$d/dst/dist"
  echo "$d"
}

cleanup() { rm -rf "$1"; }

run_sync() {
  local workdir="$1"
  # Use absolute replacement paths that don't collide with sed prefixes.
  # Inject a unique sentinel into start.sh paths first, then replace that
  # sentinel with the test-specific paths.
  local src_sentinel="__SYNC_TEST_SRC__"
  local dst_sentinel="__SYNC_TEST_DST__"
  local SRC_DIST_DIR="${workdir}/src/dist"
  local DST_STATUS_DIR="${workdir}/dst"

  extract_sync_block | sed \
    -e "s|/opt/dashcaddy/status/dist|${src_sentinel}|g" \
    -e "s|/var/www/dashcaddy-status|${dst_sentinel}|g" \
    -e "s|${src_sentinel}|${SRC_DIST_DIR}|g" \
    -e "s|${dst_sentinel}|${DST_STATUS_DIR}|g" \
  > /tmp/_sync_block.sh
  # shellcheck disable=SC1091
  source /tmp/_sync_block.sh
}

# Test 1: Bundles + sw.js + index.html all get synced from a real source tree
echo "Test 1: fresh source → files synced to status dir"
WORKDIR="$(fresh_workdir)"
SRC="${WORKDIR}/src/dist"
echo 'console.log("core");' > "${SRC}/core.js"
echo 'console.log("features");' > "${SRC}/features.js"
echo 'self.addEventListener("fetch", ...)' > "${SRC}/sw.js"
echo '<html><body>hi</body></html>' > "${SRC}/index.html"

run_sync "${WORKDIR}"

if [ -f "${WORKDIR}/dst/dist/core.js" ]; then
  pass "core.js copied to status dir"
else
  fail "core.js NOT copied"
fi
if [ -f "${WORKDIR}/dst/dist/features.js" ]; then
  pass "features.js copied"
else
  fail "features.js NOT copied"
fi
if [ -f "${WORKDIR}/dst/sw.js" ]; then
  pass "sw.js copied (NOT under dist/)"
else
  fail "sw.js NOT copied"
fi
if [ -f "${WORKDIR}/dst/index.html" ]; then
  pass "index.html copied"
else
  fail "index.html NOT copied"
fi
cleanup "${WORKDIR}"

# Test 2: Missing source dir → WARN, no exit, no crash, no destinations created
echo
echo "Test 2: source dir missing → WARN, no exit"
WORKDIR="$(fresh_workdir)"
# SRC intentionally NOT created
run_sync "${WORKDIR}"
# If we reach here without an exit code propagating, we passed
if [ -z "$(ls -A "${WORKDIR}/dst/dist" 2>/dev/null)" ]; then
  pass "no files copied when source missing"
else
  fail "files copied when source was missing — should be no-op"
fi
cleanup "${WORKDIR}"

# Test 3: Re-running syncs (idempotent — files overwritten with same content)
echo
echo "Test 3: idempotency (re-sync overwrites with same content)"
WORKDIR="$(fresh_workdir)"
SRC="${WORKDIR}/src/dist"
echo 'core-v1' > "${SRC}/core.js"
run_sync "${WORKDIR}"
echo 'core-v2' > "${SRC}/core.js"   # mutate source
run_sync "${WORKDIR}"
if [ "$(cat "${WORKDIR}/dst/dist/core.js")" = "core-v2" ]; then
  pass "second sync picked up the latest source"
else
  fail "second sync did not update"
fi
cleanup "${WORKDIR}"

# Test 4: set -e propagation — a single file-level failure doesn't take down the script
echo
echo "Test 4: set -e does not kill container start when sync hits a permission error"
WORKDIR="$(fresh_workdir)"
SRC="${WORKDIR}/src/dist"
echo 'core' > "${SRC}/core.js"
DST="${WORKDIR}/dst/dist"
chmod 555 "${DST}"   # write-protected dest → cp -f would fail
# shellcheck disable=SC1091
set -e
run_sync "${WORKDIR}"
EXIT=$?
set +e
chmod 755 "${DST}" 2>/dev/null
cleanup "${WORKDIR}"
if [ "$EXIT" -eq 0 ]; then
  pass "sync step survives a permission-denied dest"
else
  fail "set -e propagated a sync failure (exit ${EXIT}); would prevent container from starting"
fi

rm -f /tmp/_sync_block.sh

echo
if [ "$FAILURES" -eq 0 ]; then
  echo "All sync regression tests passed."
  exit 0
fi
echo "${FAILURES} test(s) failed."
exit 1
