#!/bin/sh
set -eu
BASE="https://install.cyber-vpn.cc"
LOGIN_SERVER=""
AUTH_KEY=""
while [ $# -gt 0 ]; do
  case "$1" in
    --login-server=*) LOGIN_SERVER="${1#*=}" ;;
    --login-server) shift; LOGIN_SERVER="${1:-}" ;;
    --auth-key=*) AUTH_KEY="${1#*=}" ;;
    --auth-key) shift; AUTH_KEY="${1:-}" ;;
    *) echo "unknown arg: $1" >&2; exit 2 ;;
  esac
  shift
done
[ -n "$LOGIN_SERVER" ] || { echo "missing --login-server" >&2; exit 2; }
[ -n "$AUTH_KEY" ] || { echo "missing --auth-key" >&2; exit 2; }

if [ "$(id -u)" -ne 0 ]; then
  echo "cybervpn installer needs root; re-running with sudo..."
  exec sudo sh -c "curl -fsSL $BASE | sh -s -- --login-server=$LOGIN_SERVER --auth-key=$AUTH_KEY"
fi

OS="$(uname -s)"
case "$(uname -m)" in
  x86_64|amd64) ARCH=amd64 ;;
  aarch64|arm64) ARCH=arm64 ;;
  *) echo "unsupported arch $(uname -m)" >&2; exit 1 ;;
esac

dl() {
  OSDIR="$1"
  echo "downloading cybervpn ($OSDIR/$ARCH)..."
  curl -fsSL "$BASE/dl/$OSDIR/$ARCH/cybervpn"  -o /usr/local/bin/cybervpn
  curl -fsSL "$BASE/dl/$OSDIR/$ARCH/cybervpnd" -o /usr/local/bin/cybervpnd
  chmod +x /usr/local/bin/cybervpn /usr/local/bin/cybervpnd
}

case "$OS" in
Linux)
  dl linux
  cat > /etc/systemd/system/cybervpnd.service <<UNIT
[Unit]
Description=CyberVPN daemon
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/local/bin/cybervpnd --state /var/lib/cybervpn/cybervpnd.state --socket /run/cybervpn/cybervpnd.sock --tun cybervpn0
RuntimeDirectory=cybervpn
StateDirectory=cybervpn
Restart=on-failure

[Install]
WantedBy=multi-user.target
UNIT
  systemctl daemon-reload
  systemctl enable cybervpnd
  systemctl restart cybervpnd  # start, or restart to pick up an updated binary on re-run
  SOCK=/run/cybervpn/cybervpnd.sock
  ;;
Darwin)
  dl darwin
  mkdir -p "/Library/Application Support/cybervpn"
  # No --socket: the daemon listens on the macOS default (/var/run/cybervpnd.socket) so a
  # bare cybervpn CLI (which uses that same default) finds OUR daemon, not a real Tailscale.
  cat > /Library/LaunchDaemons/net.cybervpn.daemon.plist <<PLIST
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"><dict>
  <key>Label</key><string>net.cybervpn.daemon</string>
  <key>ProgramArguments</key><array>
    <string>/usr/local/bin/cybervpnd</string>
    <string>--state</string><string>/Library/Application Support/cybervpn/cybervpnd.state</string>
    <string>--tun</string><string>userspace-networking</string>
  </array>
  <key>RunAtLoad</key><true/>
  <key>KeepAlive</key><true/>
  <key>StandardErrorPath</key><string>/var/log/cybervpnd.log</string>
  <key>StandardOutPath</key><string>/var/log/cybervpnd.log</string>
</dict></plist>
PLIST
  # Force-remove any prior (possibly crash-looping) daemon before loading the new plist:
  # 'launchctl load' on an already-loaded label is a no-op, so a stale daemon would persist.
  launchctl bootout system/net.cybervpn.daemon 2>/dev/null || true
  launchctl unload /Library/LaunchDaemons/net.cybervpn.daemon.plist 2>/dev/null || true
  pkill -x cybervpnd 2>/dev/null || true
  rm -f /var/run/cybervpnd.socket
  launchctl bootstrap system /Library/LaunchDaemons/net.cybervpn.daemon.plist 2>/dev/null     || launchctl load -w /Library/LaunchDaemons/net.cybervpn.daemon.plist
  SOCK=/var/run/cybervpnd.socket
  ;;
*)
  echo "unsupported OS $OS (Linux/macOS only)" >&2; exit 1 ;;
esac

# Wait for the daemon's localapi socket (cold start + launchd KeepAlive can take a while).
i=0; while [ ! -S "$SOCK" ] && [ $i -lt 60 ]; do i=$((i+1)); sleep 1; done
# Register, retrying a few times while the daemon settles.
ok=0
for try in 1 2 3 4 5; do
  if /usr/local/bin/cybervpn --socket "$SOCK" up --reset --login-server="$LOGIN_SERVER" --auth-key="$AUTH_KEY"; then ok=1; break; fi
  sleep 3
done
[ "$ok" = 1 ] || { echo "registration failed; see daemon log: /var/log/cybervpnd.log" >&2; exit 1; }
# Let the invoking (non-root) user drive the CLI without sudo.
[ -n "${SUDO_USER:-}" ] && /usr/local/bin/cybervpn --socket "$SOCK" set --operator="$SUDO_USER" 2>/dev/null || true
echo "CyberVPN connected. Status:"
/usr/local/bin/cybervpn --socket "$SOCK" status || true
