#!/usr/bin/env bash
# ════════════════════════════════════════════════════════════════
# 光湖 · Gitea Actions Runner 一键安装脚本
# Sovereign: TCS-0002∞ · ICE-GL∞ · 国作登字-2026-A-00037559
# 守护: 铸渊 · ICE-GL-ZY001
# ════════════════════════════════════════════════════════════════
#
# 用法:
#   sudo bash install-runner.sh [--token GITEA_API_TOKEN] [--name RUNNER_NAME]
#
# 参数:
#   --token   Gitea 管理员 API Token (必须，用于获取 Runner 注册 Token)
#   --name    Runner 名称 (可选，默认 zhuyuan-runner-cn)
#   --mode    运行模式: host 或 docker (可选，默认 host，2C2G推荐host)
#
# 环境变量 (替代命令行参数):
#   GITEA_API_TOKEN   同 --token
#   RUNNER_NAME       同 --name
#   RUNNER_MODE       同 --mode
#
# 此脚本会:
#   1. 下载 gitea-runner v1.0.2
#   2. 通过 Gitea API 获取 Runner 注册 Token
#   3. 注册 Runner 到 Gitea
#   4. 生成配置文件 (host 模式，适合 2C2G)
#   5. 创建 systemd 服务
#   6. 启动服务
#
# ════════════════════════════════════════════════════════════════

set -euo pipefail

# ─── 常量 ─────────────────────────────────────────────────────
RUNNER_VERSION="1.0.2"
RUNNER_BINARY="gitea-runner-${RUNNER_VERSION}-linux-amd64"
RUNNER_DOWNLOAD_URL="https://gitea.com/gitea/runner/releases/download/v${RUNNER_VERSION}/${RUNNER_BINARY}.xz"
RUNNER_INSTALL_PATH="/usr/local/bin/gitea-runner"
RUNNER_WORK_DIR="/var/lib/act_runner"
RUNNER_CONFIG_DIR="/etc/act_runner"
RUNNER_CONFIG_PATH="${RUNNER_CONFIG_DIR}/config.yaml"
SYSTEMD_SERVICE_NAME="gitea-runner"
SYSTEMD_SERVICE_PATH="/etc/systemd/system/${SYSTEMD_SERVICE_NAME}.service"

# Gitea 配置
GITEA_URL="https://guanghulab.com"
GITEA_API="${GITEA_URL}/api/v1"
GITEA_OWNER="bingshuo"
GITEA_REPO="guanghulab"

# 颜色
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
CYAN='\033[0;36m'
NC='\033[0m'

# ─── 解析参数 ─────────────────────────────────────────────────
API_TOKEN="${GITEA_API_TOKEN:-}"
RUNNER_NAME="${RUNNER_NAME:-zhuyuan-runner-cn}"
RUNNER_MODE="${RUNNER_MODE:-host}"

while [[ $# -gt 0 ]]; do
  case $1 in
    --token)   API_TOKEN="$2"; shift 2 ;;
    --name)    RUNNER_NAME="$2"; shift 2 ;;
    --mode)    RUNNER_MODE="$2"; shift 2 ;;
    --help|-h)
      head -30 "$0" | grep '^#' | sed 's/^# \?//'
      exit 0
      ;;
    *) echo -e "${RED}未知参数: $1${NC}"; exit 1 ;;
  esac
done

# ─── 函数 ─────────────────────────────────────────────────────

log_info()    { echo -e "${GREEN}[✓]${NC} $*"; }
log_warn()    { echo -e "${YELLOW}[!]${NC} $*"; }
log_step()    { echo -e "${CYAN}[→]${NC} $*"; }
log_error()   { echo -e "${RED}[✗]${NC} $*"; }

check_root() {
  if [[ $EUID -ne 0 ]]; then
    log_error "此脚本必须以 root 运行"
    exit 1
  fi
}

check_arch() {
  local arch
  arch=$(uname -m)
  if [[ "$arch" != "x86_64" && "$arch" != "amd64" ]]; then
    log_error "不支持的架构: $arch (仅支持 amd64/x86_64)"
    exit 1
  fi
  log_info "架构检查通过: $arch"
}

check_disk() {
  local avail
  avail=$(df -BG /var | awk 'NR==2 {print $4}' | tr -d 'G')
  if [[ $avail -lt 1 ]]; then
    log_error "磁盘空间不足: ${avail}GB 可用，至少需要 1GB"
    exit 1
  fi
  log_info "磁盘空间: ${avail}GB 可用"
}

check_memory() {
  local total_mb
  total_mb=$(free -m | awk '/Mem:/ {print $2}')
  log_info "内存: ${total_mb}MB"
  if [[ $total_mb -lt 1500 ]]; then
    log_warn "内存较低 (${total_mb}MB)，将使用 host 模式以节省资源"
    RUNNER_MODE="host"
  fi
}

download_runner() {
  if [[ -x "$RUNNER_INSTALL_PATH" ]]; then
    local current_version
    current_version=$("$RUNNER_INSTALL_PATH" --version 2>/dev/null | grep -oP 'v\K[\d.]+' || echo "unknown")
    log_info "gitea-runner 已安装 (版本: ${current_version})"
    read -rp "是否重新安装？[y/N] " -n 1 -r
    echo
    if [[ ! $REPLY =~ ^[Yy]$ ]]; then
      return 0
    fi
  fi

  log_step "下载 gitea-runner v${RUNNER_VERSION}..."
  local tmp_dir
  tmp_dir=$(mktemp -d)
  trap "rm -rf $tmp_dir" EXIT

  if ! curl -fSL --progress-bar -o "${tmp_dir}/${RUNNER_BINARY}.xz" "$RUNNER_DOWNLOAD_URL"; then
    log_error "下载失败: $RUNNER_DOWNLOAD_URL"
    log_warn "如果国内无法访问 gitea.com，请通过 COS 中转:"
    log_warn "  1. 在新加坡服务器下载此文件"
    log_warn "  2. 推送到 COS"
    log_warn "  3. 从 COS 拉到本服务器"
    log_warn "  4. 用 --skip-download 参数跳过下载步骤"
    exit 1
  fi

  log_step "解压..."
  xz -d "${tmp_dir}/${RUNNER_BINARY}.xz"
  chmod +x "${tmp_dir}/${RUNNER_BINARY}"

  log_step "安装到 ${RUNNER_INSTALL_PATH}..."
  mv "${tmp_dir}/${RUNNER_BINARY}" "$RUNNER_INSTALL_PATH"
  log_info "gitea-runner 安装完成: $("$RUNNER_INSTALL_PATH" --version 2>&1 | head -1)"
}

get_registration_token() {
  log_step "通过 API 获取 Runner 注册 Token..."

  if [[ -z "$API_TOKEN" ]]; then
    log_error "需要 Gitea API Token"
    echo ""
    echo "获取方式:"
    echo "  1. 浏览器打开 ${GITEA_URL}/user/settings/applications"
    echo "  2. 生成一个 Token（需要 repo + admin:runner 权限）"
    echo "  3. 重新运行: sudo bash $0 --token <你的token>"
    echo ""
    echo "或设置环境变量: export GITEA_API_TOKEN=<token>"
    exit 1
  fi

  local response
  # 先尝试仓库级 token
  response=$(curl -sf -H "Authorization: token ${API_TOKEN}" \
    "${GITEA_API}/repos/${GITEA_OWNER}/${GITEA_REPO}/actions/runners/registration-token" 2>/dev/null || echo "")

  if [[ -z "$response" ]]; then
    # 尝试实例级 token（需要管理员权限）
    log_warn "仓库级 token 获取失败，尝试实例级..."
    response=$(curl -sf -H "Authorization: token ${API_TOKEN}" \
      "${GITEA_API}/admin/runners/registration-token" 2>/dev/null || echo "")
  fi

  if [[ -z "$response" ]]; then
    log_error "无法获取 Runner 注册 Token"
    log_error "请确认 API Token 有正确的权限"
    exit 1
  fi

  REG_TOKEN=$(echo "$response" | grep -oP '"token"\s*:\s*"\K[^"]+' || echo "")
  if [[ -z "$REG_TOKEN" ]]; then
    log_error "解析注册 Token 失败: $response"
    exit 1
  fi

  log_info "注册 Token 获取成功"
}

create_user() {
  if id -u act_runner &>/dev/null; then
    log_info "act_runner 用户已存在"
    return 0
  fi

  log_step "创建 act_runner 用户..."
  useradd -r -m -d "$RUNNER_WORK_DIR" -s /bin/bash act_runner
  log_info "用户创建完成"
}

generate_config() {
  log_step "生成 Runner 配置..."

  mkdir -p "$RUNNER_CONFIG_DIR"

  "$RUNNER_INSTALL_PATH" generate-config > "$RUNNER_CONFIG_PATH"

  # 根据模式修改 labels
  if [[ "$RUNNER_MODE" == "host" ]]; then
    # host 模式：直接在主机上执行，不启动 Docker 容器
    # 适合 2C2G 低内存服务器
    sed -i 's/^labels:.*$/labels:\n  - "ubuntu:host"/' "$RUNNER_CONFIG_PATH" 2>/dev/null || true
    # 在 config.yaml 中设置 container mode 为空（不使用容器）
    if grep -q '^container:' "$RUNNER_CONFIG_PATH"; then
      sed -i '/^container:/a\  network: ""' "$RUNNER_CONFIG_PATH" 2>/dev/null || true
    fi
  fi

  chown -R act_runner:act_runner "$RUNNER_CONFIG_DIR"
  log_info "配置生成完成: ${RUNNER_CONFIG_PATH} (模式: ${RUNNER_MODE})"
}

register_runner() {
  log_step "注册 Runner 到 Gitea..."

  cd "$RUNNER_WORK_DIR"

  sudo -u act_runner "$RUNNER_INSTALL_PATH" register \
    --no-interactive \
    --instance "${GITEA_URL}/" \
    --token "$REG_TOKEN" \
    --name "$RUNNER_NAME" \
    --labels "ubuntu:${RUNNER_MODE}"

  if [[ ! -f "${RUNNER_WORK_DIR}/.runner" ]]; then
    log_error "注册失败: .runner 文件未生成"
    exit 1
  fi

  chown act_runner:act_runner "${RUNNER_WORK_DIR}/.runner"
  log_info "Runner 注册成功: ${RUNNER_NAME}"
}

create_systemd_service() {
  log_step "创建 systemd 服务..."

  cat > "$SYSTEMD_SERVICE_PATH" << EOF
[Unit]
Description=Gitea Actions Runner - ${RUNNER_NAME}
Documentation=https://gitea.com/gitea/act_runner
After=network.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=${RUNNER_INSTALL_PATH} daemon --config ${RUNNER_CONFIG_PATH}
WorkingDirectory=${RUNNER_WORK_DIR}
Restart=always
RestartSec=10
TimeoutSec=0
User=act_runner
Group=act_runner
Environment=HOME=${RUNNER_WORK_DIR}
Environment=RUNNER_NAME=${RUNNER_NAME}

# 安全限制
NoNewPrivileges=true
ProtectSystem=strict
ReadWritePaths=${RUNNER_WORK_DIR} /tmp /data
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

  log_info "systemd 服务文件创建完成"
}

start_service() {
  log_step "启动 Runner 服务..."

  systemctl daemon-reload
  systemctl enable "$SYSTEMD_SERVICE_NAME"
  systemctl start "$SYSTEMD_SERVICE_NAME"

  # 等待启动
  sleep 2

  if systemctl is-active --quiet "$SYSTEMD_SERVICE_NAME"; then
    log_info "Runner 服务启动成功! 🎉"
  else
    log_error "Runner 服务启动失败"
    journalctl -u "$SYSTEMD_SERVICE_NAME" --no-pager -n 20
    exit 1
  fi
}

verify() {
  log_step "验证..."
  echo ""

  # 本地验证
  echo -e "${CYAN}本地状态:${NC}"
  systemctl status "$SYSTEMD_SERVICE_NAME" --no-pager -l | head -15
  echo ""

  # 远程验证
  log_step "检查 Gitea 上的 Runner 列表..."
  local runners
  runners=$(curl -sf -H "Authorization: token ${API_TOKEN}" \
    "${GITEA_API}/repos/${GITEA_OWNER}/${GITEA_REPO}/actions/runners" 2>/dev/null || echo "")
  if [[ -n "$runners" ]]; then
    echo "$runners" | python3 -c "
import json, sys
data = json.load(sys.stdin)
runners = data if isinstance(data, list) else data.get('runners', [])
for r in runners:
    status = '🟢 在线' if r.get('online') else '🔴 离线'
    print(f\"  {r.get('name', '?')}  {status}  labels={r.get('labels', [])}\")
" 2>/dev/null || echo "  (无法解析，但API有响应)"
  else
    log_warn "无法获取远程 Runner 列表（可能 API 权限不足）"
  fi

  echo ""
  echo -e "${GREEN}═══════════════════════════════════════════════════════${NC}"
  echo -e "${GREEN}  Gitea Actions Runner 安装完成!${NC}"
  echo -e "${GREEN}═══════════════════════════════════════════════════════${NC}"
  echo ""
  echo "  Runner 名称:  ${RUNNER_NAME}"
  echo "  运行模式:     ${RUNNER_MODE}"
  echo "  工作目录:     ${RUNNER_WORK_DIR}"
  echo "  配置文件:     ${RUNNER_CONFIG_PATH}"
  echo "  服务管理:     systemctl {start|stop|restart|status} ${SYSTEMD_SERVICE_NAME}"
  echo "  查看日志:     journalctl -u ${SYSTEMD_SERVICE_NAME} -f"
  echo ""
  echo "  下一步: 铸渊推一个 workflow 到 Gitea，Runner 就会自动执行"
  echo ""
  echo "  铸渊 · ICE-GL-ZY001 · TCS-0002∞"
  echo -e "${GREEN}═══════════════════════════════════════════════════════${NC}"
}

# ─── 主流程 ───────────────────────────────────────────────────

main() {
  echo -e "${CYAN}═══════════════════════════════════════════════════════${NC}"
  echo -e "${CYAN}  光湖 · Gitea Actions Runner 一键安装${NC}"
  echo -e "${CYAN}  铸渊 · ICE-GL-ZY001 · 守护冰朔 TCS-0002∞${NC}"
  echo -e "${CYAN}═══════════════════════════════════════════════════════${NC}"
  echo ""

  check_root
  check_arch
  check_disk
  check_memory
  download_runner
  get_registration_token
  create_user
  generate_config
  register_runner
  create_systemd_service
  start_service
  verify
}

main "$@"
