#!/bin/bash
# Verify upgrade from Debian unstable (0.9.9gem-6) to local build.
set -euo pipefail

LOGDIR=/tmp/stompserver-upgrade-logs
NEW_DEB=/root/stompserver-new.deb
mkdir -p "$LOGDIR"
exec > >(tee -a "$LOGDIR/full-run.log") 2>&1

section() {
  echo
  echo "================================================================"
  echo "== $1"
  echo "================================================================"
}

pass() { echo "PASS: $1"; }
fail() { echo "FAIL: $1" | tee -a "$LOGDIR/failures.log"; exit 1; }

section "Environment"
date -Is | tee "$LOGDIR/date.txt"
cat /etc/debian_version | tee "$LOGDIR/debian-version.txt"
apt-cache policy stompserver | tee "$LOGDIR/apt-policy-before.txt"

section "Install stompserver 0.9.9gem-6 from Debian unstable"
DEBIAN_FRONTEND=noninteractive apt-get update -qq
DEBIAN_FRONTEND=noninteractive apt-get install -y -qq \
  stompserver=0.9.9gem-6 \
  ruby ruby-daemons ruby-eventmachine ruby-hoe adduser systemd 2>&1 | tee "$LOGDIR/apt-install-old.txt"
dpkg -s stompserver | tee "$LOGDIR/dpkg-status-old.txt"
test -f /etc/init.d/stompserver && pass "old package provides SysV init script"
test ! -f /usr/lib/systemd/system/stompserver.service && pass "old package has no systemd unit"

section "Seed custom configuration (simulates admin edits)"
MARKER="upgrade-test-marker-$(date +%s)"
cp -a /etc/stompserver/stompserver.conf "$LOGDIR/stompserver.conf.before"
cat >> /etc/stompserver/stompserver.conf <<EOF

# ${MARKER}
:host: 127.0.0.1
:port: 61613
EOF
grep -q "$MARKER" /etc/stompserver/stompserver.conf
pass "custom config marker written"
cat /etc/stompserver/stompserver.conf | tee "$LOGDIR/stompserver.conf.custom"

section "Start and verify old init-script service"
# Sid redirects init.d to systemctl; skip that for the legacy package.
SYSTEMCTL_SKIP_REDIRECT=1 /etc/init.d/stompserver start 2>&1 | tee "$LOGDIR/init-start.txt"
sleep 2
SYSTEMCTL_SKIP_REDIRECT=1 /etc/init.d/stompserver status 2>&1 | tee "$LOGDIR/init-status.txt"
ss -tlnp | grep 61613 | tee "$LOGDIR/ss-before-upgrade.txt"
pass "old init script starts server"

# Note: 0.9.9gem-6 is broken for STOMP clients on Ruby 3.3+; verify only that
# the legacy init script brings up a listener.
ruby -rsocket -e 'TCPSocket.new("127.0.0.1",61613).close; puts "TCP 61613 open"' \
  2>&1 | tee "$LOGDIR/tcp-before-upgrade.txt"
grep -q 'TCP 61613 open' "$LOGDIR/tcp-before-upgrade.txt" && pass "listener up before upgrade"

section "Stop legacy service before upgrade"
SYSTEMCTL_SKIP_REDIRECT=1 /etc/init.d/stompserver stop 2>&1 | tee "$LOGDIR/init-stop.txt"
sleep 1

section "Upgrade to local 0.9.9gem-7 package"
test -f "$NEW_DEB" || fail "missing $NEW_DEB"
DEBIAN_FRONTEND=noninteractive dpkg -i "$NEW_DEB" 2>&1 | tee "$LOGDIR/dpkg-upgrade.txt"
DEBIAN_FRONTEND=noninteractive apt-get install -y -f -qq 2>&1 | tee -a "$LOGDIR/dpkg-upgrade.txt"
dpkg -s stompserver | tee "$LOGDIR/dpkg-status-new.txt"
apt-cache policy stompserver | tee "$LOGDIR/apt-policy-after.txt"

section "Post-upgrade packaging checks"
test ! -e /etc/init.d/stompserver && pass "SysV init script removed on upgrade"
test -f /usr/lib/systemd/system/stompserver.service && pass "systemd unit installed on upgrade"
test -f /usr/lib/tmpfiles.d/stompserver.conf && pass "tmpfiles snippet present after upgrade"
grep -q deb-systemd-invoke /etc/logrotate.d/stompserver && pass "logrotate migrated to systemd invoke"
grep -q "$MARKER" /etc/stompserver/stompserver.conf && pass "admin config marker preserved"
grep -q ':host: 127.0.0.1' /etc/stompserver/stompserver.conf && pass "custom host preserved"
diff -u "$LOGDIR/stompserver.conf.before" /etc/stompserver/stompserver.conf | tee "$LOGDIR/stompserver.conf.diff" || true
pass "conffile diff captured (admin marker must remain)"

section "Post-upgrade systemd state"
systemctl is-enabled stompserver.service | tee "$LOGDIR/systemctl-enabled.txt"
sleep 2
systemctl is-active stompserver.service | tee "$LOGDIR/systemctl-active.txt"
systemctl status stompserver.service --no-pager | tee "$LOGDIR/systemctl-status.txt"
journalctl -u stompserver.service --no-pager -n 30 | tee "$LOGDIR/journal-after-upgrade.txt"
ss -tlnp | grep 61613 | tee "$LOGDIR/ss-after-upgrade.txt"
pass "systemd service active after upgrade"

section "Post-upgrade STOMP functional smoke test"
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
install -m 0644 "$SCRIPT_DIR/stomp_client_lib.rb" /tmp/stomp_client_lib.rb

cat > /tmp/stomp_post_upgrade.rb <<'RUBY'
require '/tmp/stomp_client_lib.rb'
c = StompClient.new('127.0.0.1', 61613)
c.send_frame('CONNECT', {'accept-version' => '1.0', 'host' => 'localhost'})
cmd, = c.read_frame
raise "expected CONNECTED, got #{cmd}" unless cmd == 'CONNECTED'
c.send_frame('SEND', {'destination' => '/queue/post-upgrade'}, 'after-upgrade')
c.send_frame('SUBSCRIBE', {'destination' => '/queue/post-upgrade', 'id' => 'sub-1', 'ack' => 'auto'})
cmd, _h, body = c.read_frame
raise "expected MESSAGE, got #{cmd}" unless cmd == 'MESSAGE'
raise "bad body #{body}" unless body == 'after-upgrade'
c.send_frame('DISCONNECT')
c.close
puts 'STOMP smoke after upgrade OK'
RUBY
ruby /tmp/stomp_post_upgrade.rb 2>&1 | tee "$LOGDIR/stomp-after-upgrade.txt"
grep -q 'STOMP smoke after upgrade OK' "$LOGDIR/stomp-after-upgrade.txt" && pass "STOMP works after upgrade"

section "Lintian on new package (host-equivalent flags, Sid)"
apt-get install -y -qq lintian 2>/dev/null
lintian -EvIiL +pedantic \
  --suppress-tags bad-distribution-in-changes-file,changelog-distribution-does-not-match-changes-file,malformed-deb-archive \
  "$NEW_DEB" 2>&1 | tee "$LOGDIR/lintian.txt"
test ! -s "$LOGDIR/lintian.txt" && pass "lintian clean (with zst deb suppressions)"

section "SUMMARY"
echo "Upgrade test completed successfully."
ls -la "$LOGDIR" | tee "$LOGDIR/INDEX.txt"