#!/usr/bin/env bash
# Create a Proxmox LXC container that installs/runs an Enshrouded dedicated server via SteamCMD.
# Run on the Proxmox host as root.
#
# Example:
#   VMID=120 STORAGE=local-lvm BRIDGE=vmbr0 IP_CIDR=192.168.0.120/24 GATEWAY=192.168.0.1 \
#     bash scripts/proxmox-create-enshrouded-lxc.sh
#
# Notes:
# - Enshrouded dedicated server is Windows-based, so this uses Wine in the LXC.
# - LXC + Wine/game servers can be finicky. If this fails, a dedicated VM is usually safer.
# - This script avoids overwriting an existing container ID.

set -euo pipefail

VMID="${VMID:-120}"
HOSTNAME="${HOSTNAME:-enshrouded}"
STORAGE="${STORAGE:-local-lvm}"
TEMPLATE_STORAGE="${TEMPLATE_STORAGE:-local}"
BRIDGE="${BRIDGE:-vmbr0}"
IP_CIDR="${IP_CIDR:-dhcp}"
GATEWAY="${GATEWAY:-}"
CORES="${CORES:-4}"
MEMORY_MB="${MEMORY_MB:-8192}"
SWAP_MB="${SWAP_MB:-2048}"
DISK_GB="${DISK_GB:-40}"
PASSWORD="${PASSWORD:-changeme-change-after-login}"
SERVER_NAME="${SERVER_NAME:-Enshrouded Dedicated Server}"
SERVER_PASSWORD="${SERVER_PASSWORD:-ChangeMe123}"
GAME_PORT="${GAME_PORT:-15636}"
QUERY_PORT="${QUERY_PORT:-15637}"
STEAM_APP_ID="${STEAM_APP_ID:-2278520}"
TEMPLATE="${TEMPLATE:-debian-12-standard_12.7-1_amd64.tar.zst}"
TEMPLATE_PATH="/var/lib/vz/template/cache/${TEMPLATE}"

if [[ $EUID -ne 0 ]]; then
  echo "ERROR: run this script as root on the Proxmox host" >&2
  exit 1
fi

command -v pct >/dev/null || { echo "ERROR: pct command not found; run on Proxmox host" >&2; exit 1; }

if pct status "$VMID" >/dev/null 2>&1; then
  echo "ERROR: container VMID $VMID already exists" >&2
  exit 1
fi

if [[ ! -f "$TEMPLATE_PATH" ]]; then
  echo "Template not found: $TEMPLATE_PATH"
  echo "Updating template list and downloading $TEMPLATE..."
  pveam update
  pveam download "$TEMPLATE_STORAGE" "$TEMPLATE"
fi

NET0="name=eth0,bridge=${BRIDGE},firewall=1"
if [[ "$IP_CIDR" == "dhcp" ]]; then
  NET0+=",ip=dhcp"
else
  NET0+=",ip=${IP_CIDR}"
  [[ -n "$GATEWAY" ]] && NET0+=",gw=${GATEWAY}"
fi

echo "Creating LXC $VMID ($HOSTNAME)..."
pct create "$VMID" "$TEMPLATE_PATH" \
  --hostname "$HOSTNAME" \
  --storage "$STORAGE" \
  --rootfs "${STORAGE}:${DISK_GB}" \
  --cores "$CORES" \
  --memory "$MEMORY_MB" \
  --swap "$SWAP_MB" \
  --password "$PASSWORD" \
  --unprivileged 1 \
  --features nesting=1,keyctl=1,fuse=1 \
  --net0 "$NET0" \
  --onboot 1 \
  --start 1

echo "Waiting for container boot..."
sleep 8

STEAMCMD_SEED_DIR=""
if command -v docker >/dev/null 2>&1; then
  echo "Docker found on host; preparing a known-working SteamCMD seed from cm2network/steamcmd..."
  STEAMCMD_SEED_DIR="$(mktemp -d)"
  if docker run --rm -v "${STEAMCMD_SEED_DIR}:/out" cm2network/steamcmd sh -lc './steamcmd.sh +quit && tar -C /home/steam/steamcmd -czf /out/steamcmd-fixed.tgz .' ; then
    pct push "$VMID" "${STEAMCMD_SEED_DIR}/steamcmd-fixed.tgz" /tmp/steamcmd-fixed.tgz
  else
    echo "WARNING: SteamCMD seed creation failed; falling back to Valve bootstrap tarball inside the LXC."
  fi
else
  echo "Docker not found on host; using Valve bootstrap tarball inside the LXC."
fi

echo "Provisioning Enshrouded server inside LXC..."
pct exec "$VMID" -- bash -s <<'IN_CONTAINER'
set -euo pipefail

export DEBIAN_FRONTEND=noninteractive

apt-get update
apt-get install -y --no-install-recommends \
  ca-certificates curl file tar unzip xz-utils procps locales jq \
  lib32gcc-s1 lib32stdc++6 libc6-i386 \
  wine wine64 xvfb

locale-gen en_US.UTF-8 || true

id steam >/dev/null 2>&1 || useradd -m -s /bin/bash steam
mkdir -p /opt/enshrouded /opt/steamcmd /var/log/enshrouded
chown -R steam:steam /opt/enshrouded /opt/steamcmd /var/log/enshrouded

if [[ -f /tmp/steamcmd-fixed.tgz ]]; then
  echo "Installing pre-seeded SteamCMD from host-created archive..."
  tar -xzf /tmp/steamcmd-fixed.tgz -C /opt/steamcmd
  chown -R steam:steam /opt/steamcmd
fi

cat >/usr/local/bin/enshrouded-update <<'EOS'
#!/usr/bin/env bash
set -euo pipefail
cd /opt/steamcmd
if [[ ! -x ./steamcmd.sh ]]; then
  curl -fsSL https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz -o steamcmd_linux.tar.gz
  tar -xzf steamcmd_linux.tar.gz
fi
./steamcmd.sh +force_install_dir /opt/enshrouded +login anonymous +app_update 2278520 validate +quit
EOS
chmod +x /usr/local/bin/enshrouded-update

su -s /bin/bash steam -c /usr/local/bin/enshrouded-update

# Create/update default config if SteamCMD did not create one yet.
if [[ ! -f /opt/enshrouded/enshrouded_server.json ]]; then
  cat >/opt/enshrouded/enshrouded_server.json <<EOS
{
  "name": "__SERVER_NAME__",
  "password": "__SERVER_PASSWORD__",
  "saveDirectory": "./savegame",
  "logDirectory": "./logs",
  "ip": "0.0.0.0",
  "gamePort": __GAME_PORT__,
  "queryPort": __QUERY_PORT__,
  "slotCount": 16
}
EOS
fi
chown -R steam:steam /opt/enshrouded

cat >/etc/systemd/system/enshrouded.service <<'EOS'
[Unit]
Description=Enshrouded Dedicated Server
Wants=network-online.target
After=network-online.target

[Service]
Type=simple
User=steam
Group=steam
WorkingDirectory=/opt/enshrouded
Environment=HOME=/home/steam
Environment=WINEPREFIX=/home/steam/.wine-enshrouded
ExecStartPre=/usr/local/bin/enshrouded-update
ExecStart=/usr/bin/wine64 /opt/enshrouded/enshrouded_server.exe
Restart=on-failure
RestartSec=15
StandardOutput=append:/var/log/enshrouded/server.log
StandardError=append:/var/log/enshrouded/server.err
LimitNOFILE=100000

[Install]
WantedBy=multi-user.target
EOS

systemctl daemon-reload
systemctl enable enshrouded.service
IN_CONTAINER

# Substitute host-provided config values after heredoc provisioning.
pct exec "$VMID" -- bash -c "sed -i \
  -e 's#__SERVER_NAME__#${SERVER_NAME//\/\\}#g' \
  -e 's#__SERVER_PASSWORD__#${SERVER_PASSWORD//\/\\}#g' \
  -e 's#__GAME_PORT__#${GAME_PORT}#g' \
  -e 's#__QUERY_PORT__#${QUERY_PORT}#g' \
  /opt/enshrouded/enshrouded_server.json"

pct exec "$VMID" -- chown steam:steam /opt/enshrouded/enshrouded_server.json

echo "Starting Enshrouded service..."
pct exec "$VMID" -- systemctl restart enshrouded.service || true

echo
 echo "Done. Useful commands:"
echo "  pct enter $VMID"
echo "  pct exec $VMID -- systemctl status enshrouded --no-pager"
echo "  pct exec $VMID -- journalctl -u enshrouded -n 100 --no-pager"
echo "  pct exec $VMID -- tail -f /var/log/enshrouded/server.log /var/log/enshrouded/server.err"
echo
 echo "Ports to allow/forward if needed: UDP ${GAME_PORT}, UDP ${QUERY_PORT}"
echo "Initial root password was set from PASSWORD env var; change it if you used the default."

if [[ -n "${STEAMCMD_SEED_DIR:-}" ]]; then
  rm -rf "$STEAMCMD_SEED_DIR"
fi
