#!/bin/sh
# easyso-setup.sh — a new EasySo server on this VPS, from your phone's doormat.
# claude 2026-11-09: user — no nginx, no certificate, no domain: put this file,
# easyso-amd64 (or easyso-arm64) and bootstrappers.csv in one folder, then:
#   sh easyso-setup.sh
# It opens the 4 EasySo ports, places the right binary, the live IPs and the
# release files (served to the next new server) in /home/easyso, makes the
# server's key (an existing key is never replaced) and starts the server,
# again after every reboot.
set -e
[ "$(id -u)" = 0 ] || exec sudo sh "$0" "$@"
OWNER=   # claude 2026-11-10: user — the DID whose phone manages this server (My servers)
HOMEDIR= # claude 2026-11-10: user — EasySo's folder, if the user named one (default: the account's, /home/easyso)
while [ $# -gt 0 ]; do case $1 in --owner) OWNER=$2; shift 2 ;; --home) HOMEDIR=$2; shift 2 ;; *) shift ;; esac; done
case $HOMEDIR in ""|/home/easyso) HOMEDIR= ;; /*[!A-Za-z0-9/._-]*) echo "EasySo folder $HOMEDIR: letters, digits, / . _ - only"; exit 1 ;; /?*) ;; *) echo "EasySo folder must be a full path, like /home/easyso"; exit 1 ;; esac
D=$(cd "$(dirname "$0")" && pwd)
# claude 2026-11-10: user — the system and chip detected, never asked
[ "$(uname -s)" = Linux ] || { echo "This VPS runs $(uname -s): EasySo servers run on Linux. Rent a Linux VPS (Ubuntu, Debian, CentOS, Rocky …)."; exit 1; }
case $(uname -m) in
  x86_64|amd64) A=amd64 ;;
  aarch64|arm64|armv8*) A=arm64 ;;
  *) echo "This VPS's chip is $(uname -m): EasySo servers run on x86-64 or ARM64. Rent one of those."; exit 1 ;;
esac
B=$D/easyso-$A; C=$D/bootstrappers.csv
[ -f "$B" ] || { echo "easyso-$A is missing: save it from your phone (EasySo software) into $D"; exit 1; }
if [ -f "$D/SHA256SUMS" ] && grep -q " easyso-$A\$" "$D/SHA256SUMS"; then
  (cd "$D" && grep " easyso-$A\$" SHA256SUMS | sha256sum -c --quiet) || { echo "easyso-$A does not match SHA256SUMS: get it again"; exit 1; }
fi
echo "easyso-$A  $(sha256sum "$B" | cut -c1-16)…  (the same as your phone's list?)"

# 1 the 4 ports: UDP 17939, TCP 28633 21487 26041
if command -v ufw >/dev/null && ufw status | grep -q "Status: active"; then
  ufw allow 17939/udp >/dev/null; for p in 28633 21487 26041; do ufw allow $p/tcp >/dev/null; done
elif command -v firewall-cmd >/dev/null && firewall-cmd --state >/dev/null 2>&1; then
  firewall-cmd -q --permanent --add-port=17939/udp
  for p in 28633 21487 26041; do firewall-cmd -q --permanent --add-port=$p/tcp; done; firewall-cmd -q --reload
elif command -v iptables >/dev/null; then
  iptables -C INPUT -p udp --dport 17939 -j ACCEPT 2>/dev/null || iptables -I INPUT -p udp --dport 17939 -j ACCEPT
  for p in 28633 21487 26041; do iptables -C INPUT -p tcp --dport $p -j ACCEPT 2>/dev/null || iptables -I INPUT -p tcp --dport $p -j ACCEPT; done
  command -v netfilter-persistent >/dev/null && netfilter-persistent save >/dev/null 2>&1 || true
fi
echo "EasySo can now be reached on this VPS."

# 2 the binary and the live IPs, in the server's own account
if ! id easyso >/dev/null 2>&1; then
  if [ -n "$HOMEDIR" ]; then mkdir -p "$(dirname "$HOMEDIR")"; useradd -m -d "$HOMEDIR" -s /bin/sh easyso
  else mkdir -p /home; useradd -m -s /bin/sh easyso; fi
fi
H=$(getent passwd easyso | cut -d: -f6)
# an existing account keeps its folder: its key is never moved
[ -n "$HOMEDIR" ] && [ "$HOMEDIR" != "$H" ] && echo "EasySo already lives in $H on this VPS (its key stays there): $HOMEDIR not used"
mkdir -p "$H" && chown easyso:easyso "$H" && chmod 750 "$H"   # claude 2026-11-10: a leftover folder becomes its own
command -v systemctl >/dev/null && systemctl stop easyso 2>/dev/null || true
pkill -u easyso -x easyso 2>/dev/null && sleep 2 || true
install -o easyso -g easyso -m 755 "$B" "$H/easyso"
# claude 2026-11-10: SELinux (Red Hat family) forbids systemd to run a program
# under /home unless it is marked as one (bwchain.net: no node.log at all)
command -v chcon >/dev/null && chcon -t bin_t "$H/easyso" 2>/dev/null || true
# an account from an earlier chain: its key is kept, its old chain set aside
# (never deleted) — the server starts on today's chain
if [ -d "$H/data" ] && [ ! -f "$H/node.log" ] && [ -n "$(ls -A "$H/data" 2>/dev/null)" ]; then
  mv "$H/data" "$H/data.before-$(date +%Y%m%d%H%M)"; install -d -m700 -o easyso -g easyso "$H/data"
fi
[ -f "$C" ] && install -o easyso -g easyso -m 644 "$C" "$H/bootstrappers.csv"
# the release files too: this server then bootstraps the next new one
install -d -o easyso -g easyso "$H/download"
if [ -f "$D/SHA256SUMS" ]; then
  for f in $(awk '{print $2}' "$D/SHA256SUMS") SHA256SUMS; do
    if [ -f "$D/$f" ]; then install -o easyso -g easyso -m 644 "$D/$f" "$H/download/$f"; fi
  done
fi
if [ -n "$OWNER" ] && ! grep -qx "$OWNER" "$H/OWNERS.txt" 2>/dev/null; then
  echo "$OWNER" >> "$H/OWNERS.txt"; chown easyso:easyso "$H/OWNERS.txt"
fi
[ -f "$H/key/private.toml" ] || su easyso -c "cd ~ && echo yes | ./easyso keypair >/dev/null 2>&1"
[ -f "$H/key/private.toml" ] || { echo "no key made: see $H"; exit 1; }

# start, and again after every reboot
if command -v systemctl >/dev/null && [ -d /run/systemd/system ]; then
  cat > /etc/systemd/system/easyso.service <<EOF
[Unit]
Description=EasySo server
After=network-online.target
Wants=network-online.target
[Service]
User=easyso
WorkingDirectory=$H
ExecStart=/bin/sh -c "exec $H/easyso server >>$H/node.log 2>&1"
Restart=on-failure
RestartSec=10
[Install]
WantedBy=multi-user.target
EOF
  systemctl daemon-reload; systemctl enable -q --now easyso
else
  su easyso -c "cd ~ && nohup ./easyso server >>node.log 2>&1 </dev/null &"
fi
sleep 5
if ! pgrep -u easyso -x easyso >/dev/null; then   # claude 2026-11-10: the reason, from wherever it went
  echo "the server did not start:"
  [ -s "$H/node.log" ] && tail -15 "$H/node.log"
  command -v journalctl >/dev/null && journalctl -u easyso -n 15 --no-pager 2>/dev/null | tail -15
  exit 1
fi
DID=$(grep -A1 "PublicKey (NodeID)" "$H/node.log" | tail -1 | grep -oE '[0-9a-f]{64,}' | head -1)
echo "EasySo server running. DID: ${DID:-see $H/node.log}"
echo "Back up $H/key (the server's key), as you did your phone's."
IP=$(curl -s4 --max-time 8 https://1.1.1.1/cdn-cgi/trace 2>/dev/null | sed -n 's/^ip=//p')
[ -n "$OWNER" ] && echo "Managed from your phone: EasySo → My servers → add ${IP:-this VPS's IP}"
