#!/usr/bin/env bash
# Botmaster proxy and Actions Gateway activate independently from the grouped web release.
set -uo pipefail

ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
SCRIPT="$ROOT/packaging/deploy-local.sh"
fails=0
check() { if [[ "$1" == 0 ]]; then printf 'ok - %s\n' "$2"; else printf 'FAIL - %s\n' "$2"; fails=$((fails + 1)); fi; }

bash -n "$SCRIPT"
check "$?" 'deploy-local.sh parses'

for component in botmaster-proxy actions-gateway; do
  activate_line=$(grep -n "backend-release.sh\" activate $component" "$SCRIPT" | head -1 | cut -d: -f1)
  receipt_line=$(grep -n "publish_component_receipt $component \"\$deployment_sha\"" "$SCRIPT" | head -1 | cut -d: -f1)
  if [[ -n "$activate_line" && -n "$receipt_line" ]] && (( activate_line < receipt_line )); then rc=0; else rc=1; fi
  check "$rc" "$component activation precedes its convergence receipt"
done

if ! grep -q 'release_restart_services+=(botmaster-proxy.service)' "$SCRIPT" \
  && grep -q 'for component in web web-watchdog' "$SCRIPT"; then rc=0; else rc=1; fi
check "$rc" 'web rollback neither restarts nor republishes Botmaster proxy convergence'

if grep -q 'actions-gateway-readiness.sh' "$SCRIPT" \
  && grep -q 'select-inactive actions-gateway' "$SCRIPT" \
  && grep -q 'keep_service_dark "$ACTIONS_GATEWAY_SERVICE"' "$SCRIPT"; then rc=0; else rc=1; fi
check "$rc" 'configured Gateway uses typed authenticated activation while missing config stays dark on exact source'

if grep -q 'botmaster_bootstrap_sha="$botmaster_base"' "$SCRIPT" \
  && grep -q 'gateway_bootstrap_sha="$gateway_base"' "$SCRIPT" \
  && grep -q 'active Botmaster proxy has no exact prior revision for rollback' "$SCRIPT" \
  && grep -q 'active Actions Gateway has no exact prior revision for rollback' "$SCRIPT"; then rc=0; else rc=1; fi
check "$rc" 'first immutable migration preserves an exact prior release for every active service'

if ! grep -q 'modules/actions-gateway/dist' "$SCRIPT" \
  && ! grep -q 'rollback_actions_gateway' "$SCRIPT"; then rc=0; else rc=1; fi
check "$rc" 'deployment never builds into or restores mutable checkout output'

TESTROOT="${XDG_CACHE_HOME:-$HOME/.cache}/overdeck/tests/backend-service-gates/run-$$-$RANDOM"
FIXTURE="$TESTROOT/repo"
GATES="$TESTROOT/gates.sh"
mkdir -p "$FIXTURE/packaging" "$FIXTURE/modules/botmaster/notify" "$FIXTURE/modules/actions-gateway" "$FIXTURE/docs"
trap 'rm -rf "$TESTROOT"' EXIT
sed -n '/^service_unchanged_since_stamp() (/,/^)/p' "$SCRIPT" >"$GATES"
sed -n '/^keep_service_dark() {/,/^}/p' "$SCRIPT" >>"$GATES"
git init -q "$FIXTURE"
printf v1 >"$FIXTURE/packaging/botmaster-proxy.ts"
printf v1 >"$FIXTURE/modules/actions-gateway/server.ts"
git -C "$FIXTURE" add -A
git -C "$FIXTURE" -c user.name=t -c user.email=t@t commit -qm base
BASE=$(git -C "$FIXTURE" rev-parse HEAD)
printf note >"$FIXTURE/docs/note.md"
git -C "$FIXTURE" add -A
git -C "$FIXTURE" -c user.name=t -c user.email=t@t commit -qm docs
DOCS=$(git -C "$FIXTURE" rev-parse HEAD)
printf v2 >"$FIXTURE/modules/botmaster/notify/waker.ts"
git -C "$FIXTURE" add -A
git -C "$FIXTURE" -c user.name=t -c user.email=t@t commit -qm botmaster
BOT=$(git -C "$FIXTURE" rev-parse HEAD)
printf v2 >"$FIXTURE/modules/actions-gateway/server.ts"
git -C "$FIXTURE" add -A
git -C "$FIXTURE" -c user.name=t -c user.email=t@t commit -qm gateway
GATEWAY=$(git -C "$FIXTURE" rev-parse HEAD)

run_gate() {
  local service=$1 base=$2 target=$3 active_rc=$4; shift 4
  ( DEPLOY="$FIXTURE"; systemctl() { return "$active_rc"; }; source "$GATES"; service_unchanged_since_stamp "$service" "$base" "$target" "$@" )
}
run_gate botmaster-proxy.service "$BASE" "$DOCS" 0 packaging/botmaster-proxy.ts modules/botmaster/notify/
check "$?" 'unrelated changes keep an active Botmaster proxy'
! run_gate botmaster-proxy.service "$DOCS" "$BOT" 0 packaging/botmaster-proxy.ts modules/botmaster/notify/
check "$?" 'Botmaster runtime changes require immutable activation'
! run_gate actions-gateway.service "$BOT" "$GATEWAY" 0 modules/actions-gateway/
check "$?" 'Actions Gateway source changes require immutable activation'
! run_gate actions-gateway.service "$BASE" "$DOCS" 3 modules/actions-gateway/
check "$?" 'an inactive configured Gateway requires immutable activation'

run_dark() {
  local mutate_rc=$1 active_rc=$2 enabled_rc=$3
  (
    source "$GATES"
    systemctl() {
      case "$2" in
        stop|disable) return "$mutate_rc" ;;
        is-active) return "$active_rc" ;;
        is-enabled) return "$enabled_rc" ;;
        *) return 99 ;;
      esac
    }
    keep_service_dark actions-gateway.service
  )
}
run_dark 5 3 3
check "$?" 'a never-installed Gateway already satisfies the dark state'
! run_dark 1 0 3
check "$?" 'dark selection refuses a Gateway that remains active'
! run_dark 1 3 0
check "$?" 'dark selection refuses a Gateway that remains enabled'

(( fails == 0 )) || { printf '%s check(s) failed\n' "$fails" >&2; exit 1; }
printf 'backend-service-restart-gate: all checks passed\n'
