#!/bin/sh
# OpenServer 探针安装脚本
#
# 用法（完整命令在 App 中复制，令牌只对这台服务器有效）：
#   curl -fsSL https://get.openserver.app | sudo sh -s -- --token ost_...
#
# 可选参数：
#   --docker            同时读取 Docker 容器状态（会把 openserver 用户加入 docker 组）
#   --endpoint URL      上报地址，默认 https://ingest.openserver.app
#   --version VERSION   安装指定版本，默认最新版
#
# 已安装时不带 --token 运行，只会升级程序并保留现有配置。
set -eu

BASE_URL="${OPENSERVER_BASE_URL:-https://get.openserver.app}"
ENDPOINT="https://ingest.openserver.app"
TOKEN=""
DOCKER="no"
VERSION="latest"
CONFIG="/etc/openserver/agent.toml"
BINARY="/usr/local/bin/openserver-agent"
UNIT="/etc/systemd/system/openserver-agent.service"

ok() { printf '[ok] %s\n' "$1"; }
fail() { printf '[!!] %s\n' "$1" >&2; exit 1; }

while [ $# -gt 0 ]; do
	case "$1" in
	--token) [ $# -ge 2 ] || fail "--token 需要一个值"; TOKEN="$2"; shift 2 ;;
	--endpoint) [ $# -ge 2 ] || fail "--endpoint 需要一个值"; ENDPOINT="$2"; shift 2 ;;
	--version) [ $# -ge 2 ] || fail "--version 需要一个值"; VERSION="$2"; shift 2 ;;
	--docker) DOCKER="yes"; shift ;;
	*) fail "未知参数：$1" ;;
	esac
done

[ "$(id -u)" -eq 0 ] || fail "需要 root 权限，请在命令前加 sudo"
[ "$(uname -s)" = "Linux" ] || fail "探针只支持 Linux"
command -v systemctl >/dev/null 2>&1 && [ -d /run/systemd/system ] || fail "需要 systemd"
if [ -z "$TOKEN" ] && [ ! -f "$CONFIG" ]; then
	fail "缺少安装令牌，请在 App 中复制完整的安装命令"
fi
case "$VERSION" in
*[!A-Za-z0-9._-]*) fail "版本号格式无效" ;;
esac

case "$(uname -m)" in
x86_64 | amd64) ARCH="amd64" ;;
aarch64 | arm64) ARCH="arm64" ;;
*) fail "暂不支持的处理器架构：$(uname -m)" ;;
esac

download() {
	if command -v curl >/dev/null 2>&1; then
		curl -fsSL --retry 3 -o "$2" "$1"
	elif command -v wget >/dev/null 2>&1; then
		wget -q -O "$2" "$1"
	else
		fail "需要 curl 或 wget"
	fi
}

sha256() {
	if command -v sha256sum >/dev/null 2>&1; then
		sha256sum "$1" | cut -d' ' -f1
	else
		shasum -a 256 "$1" | cut -d' ' -f1
	fi
}

TMP="$(mktemp -d)"
trap 'rm -rf "$TMP"' EXIT

URL="$BASE_URL/agent/$VERSION/openserver-agent-linux-$ARCH"
download "$URL" "$TMP/openserver-agent" || fail "下载探针失败：$URL"
download "$URL.sha256" "$TMP/openserver-agent.sha256" || fail "下载校验文件失败"
[ "$(cut -d' ' -f1 <"$TMP/openserver-agent.sha256")" = "$(sha256 "$TMP/openserver-agent")" ] || fail "探针程序校验失败，已停止安装"

if ! id openserver >/dev/null 2>&1; then
	NOLOGIN="$(command -v nologin || echo /bin/false)"
	useradd --system --no-create-home --home-dir /nonexistent --shell "$NOLOGIN" openserver
	ok "已创建系统用户 openserver"
fi
if [ "$DOCKER" = "yes" ]; then
	if getent group docker >/dev/null 2>&1; then
		usermod -aG docker openserver
		ok "已允许探针读取 Docker 状态"
	else
		printf '[!!] 没有找到 docker 组，跳过 Docker 采集\n'
		DOCKER="no"
	fi
fi

install -m 0755 "$TMP/openserver-agent" "$BINARY"
ok "已安装 $BINARY（$("$BINARY" version)）"

if [ -n "$TOKEN" ]; then
	if [ "$DOCKER" = "yes" ]; then
		"$BINARY" enroll --token "$TOKEN" --endpoint "$ENDPOINT" --config "$CONFIG" --docker
	else
		"$BINARY" enroll --token "$TOKEN" --endpoint "$ENDPOINT" --config "$CONFIG"
	fi
fi
chown root:openserver /etc/openserver "$CONFIG"
chmod 0750 /etc/openserver
chmod 0640 "$CONFIG"

# 与仓库中 packaging/openserver-agent.service 保持一致
cat >"$UNIT" <<'EOF'
[Unit]
Description=OpenServer agent
Documentation=https://openserver.app/docs/agent
After=network-online.target
Wants=network-online.target

[Service]
User=openserver
Group=openserver
ExecStart=/usr/local/bin/openserver-agent run --config /etc/openserver/agent.toml
Restart=always
RestartSec=5
StateDirectory=openserver
StateDirectoryMode=0750
NoNewPrivileges=yes
ProtectSystem=strict
ProtectHome=read-only
PrivateTmp=yes
PrivateDevices=yes
ProtectKernelTunables=yes
ProtectKernelModules=yes
ProtectControlGroups=yes
RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6
RestrictNamespaces=yes
LockPersonality=yes
MemoryMax=128M

[Install]
WantedBy=multi-user.target
EOF
systemctl daemon-reload
systemctl enable openserver-agent.service >/dev/null 2>&1
systemctl restart openserver-agent.service
ok "已注册服务 openserver-agent.service"

sleep 3
if systemctl is-active --quiet openserver-agent.service; then
	ok "已连接 OpenServer，开始上报"
	printf '\n大约 1 分钟后，App 会显示这台服务器的健康报告。\n'
	printf '查看状态：sudo openserver-agent status\n卸载：sudo openserver-agent uninstall\n'
else
	fail "探针没有正常启动，请运行 journalctl -u openserver-agent 查看原因"
fi
