#!/usr/bin/env bash
set -Eeuo pipefail

RUNNER_VERSION="${RUNNER_VERSION:-2.0.0}"
RUNNER_USER="${RUNNER_USER:-act_runner}"
RUNNER_HOME="${RUNNER_HOME:-/var/lib/act_runner}"
RUNNER_CONFIG_DIR="${RUNNER_CONFIG_DIR:-/etc/act_runner}"
RUNNER_CONFIG_FILE="${RUNNER_CONFIG_FILE:-$RUNNER_CONFIG_DIR/config.yaml}"
RUNNER_BINARY_PATH="${RUNNER_BINARY_PATH:-/usr/local/bin/gitea-runner}"
RUNNER_COMPAT_SYMLINK_PATH="${RUNNER_COMPAT_SYMLINK_PATH:-/usr/local/bin/act_runner}"
RUNNER_NAME="${RUNNER_NAME:-$(hostname)}"
RUNNER_LABELS="${RUNNER_LABELS:-linux_amd64:host,ubuntu-latest:docker://node:20-bookworm}"
GITEA_INSTANCE_URL="${GITEA_INSTANCE_URL:-}"
GITEA_RUNNER_TOKEN="${GITEA_RUNNER_TOKEN:-}"
REGISTER_RUNNER="${REGISTER_RUNNER:-true}"

detect_runner_arch() {
  case "$(uname -m)" in
    x86_64|amd64)
      echo "amd64"
      ;;
    aarch64|arm64)
      echo "arm64"
      ;;
    *)
      echo "Nicht unterstützte Architektur: $(uname -m)" >&2
      exit 1
      ;;
  esac
}

log() {
  printf '[RUNNER] %s\n' "$1"
}

require_root() {
  if [ "${EUID}" -ne 0 ]; then
    echo "Dieses Script muss als root laufen." >&2
    exit 1
  fi
}

install_packages() {
  log "Installiere Systempakete"
  apt update
  apt install -y docker.io curl wget unzip git ca-certificates python3
  systemctl enable --now docker
}

create_runner_user() {
  log "Erstelle Runner-User und Verzeichnisse"

  if ! id -u "$RUNNER_USER" >/dev/null 2>&1; then
    useradd --system --create-home --shell /bin/bash "$RUNNER_USER"
  fi

  usermod -aG docker "$RUNNER_USER"
  mkdir -p "$RUNNER_HOME" "$RUNNER_CONFIG_DIR"
  chown -R "$RUNNER_USER:$RUNNER_USER" "$RUNNER_HOME" "$RUNNER_CONFIG_DIR"
}

install_runner_binary() {
  local tmp_dir runner_arch asset_name download_url

  log "Installiere act_runner ${RUNNER_VERSION}"
  tmp_dir="$(mktemp -d)"
  runner_arch="$(detect_runner_arch)"
  asset_name="gitea-runner-${RUNNER_VERSION}-linux-${runner_arch}"
  download_url="https://dl.gitea.com/gitea-runner/${RUNNER_VERSION}/${asset_name}"

  curl -fsSL "$download_url" -o "${tmp_dir}/gitea-runner"
  install -m 0755 "${tmp_dir}/gitea-runner" "$RUNNER_BINARY_PATH"
  ln -sf "$RUNNER_BINARY_PATH" "$RUNNER_COMPAT_SYMLINK_PATH"
  rm -rf "$tmp_dir"

  "$RUNNER_BINARY_PATH" --version
}

generate_config() {
  log "Erzeuge Runner-Konfiguration"
  sudo -u "$RUNNER_USER" -H bash -lc "\"$RUNNER_BINARY_PATH\" generate-config > \"$RUNNER_CONFIG_FILE\""

  python3 - "$RUNNER_CONFIG_FILE" "$RUNNER_LABELS" <<'PY'
from pathlib import Path
import sys

config_path = Path(sys.argv[1])
labels = [label.strip() for label in sys.argv[2].split(",") if label.strip()]
content = config_path.read_text(encoding="utf-8")
lines = content.splitlines()
out = []
in_runner = False
labels_written = False
skip_existing_labels = False

for idx, line in enumerate(lines):
    stripped = line.strip()
    if stripped == "runner:":
        in_runner = True
        out.append(line)
        continue

    if in_runner and line and not line.startswith("  "):
        if not labels_written:
            out.append("  labels:")
            for label in labels:
                out.append(f"    - \"{label}\"")
            labels_written = True
        in_runner = False

    if in_runner and stripped.startswith("labels:"):
        skip_existing_labels = True
        continue

    if skip_existing_labels:
        if line.startswith("    - ") or stripped == "":
            continue
        skip_existing_labels = False

    out.append(line)

if in_runner and not labels_written:
    out.append("  labels:")
    for label in labels:
        out.append(f"    - \"{label}\"")

config_path.write_text("\n".join(out) + "\n", encoding="utf-8")
PY

  chown "$RUNNER_USER:$RUNNER_USER" "$RUNNER_CONFIG_FILE"
}

register_runner() {
  if [ "$REGISTER_RUNNER" != "true" ]; then
    log "Runner-Registrierung übersprungen"
    return
  fi

  if [ -z "$GITEA_INSTANCE_URL" ] || [ -z "$GITEA_RUNNER_TOKEN" ]; then
    echo "Für die Registrierung werden GITEA_INSTANCE_URL und GITEA_RUNNER_TOKEN benötigt." >&2
    exit 1
  fi

  log "Registriere Runner bei ${GITEA_INSTANCE_URL}"
  sudo -u "$RUNNER_USER" -H bash -lc "cd \"$RUNNER_HOME\" && rm -f .runner && \"$RUNNER_BINARY_PATH\" register --no-interactive --instance \"$GITEA_INSTANCE_URL\" --token \"$GITEA_RUNNER_TOKEN\" --name \"$RUNNER_NAME\" --labels \"$RUNNER_LABELS\""
}

install_service() {
  log "Installiere systemd-Service"
  cat >/etc/systemd/system/act_runner.service <<EOF
[Unit]
Description=Gitea Actions runner
Documentation=https://docs.gitea.com/usage/actions/act-runner
After=docker.service
Requires=docker.service

[Service]
User=${RUNNER_USER}
WorkingDirectory=${RUNNER_HOME}
ExecStart=${RUNNER_BINARY_PATH} daemon --config ${RUNNER_CONFIG_FILE}
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
EOF

  systemctl daemon-reload
  systemctl enable --now act_runner
}

print_summary() {
  log "Fertig"
  echo
  echo "Service-Status:"
  systemctl --no-pager --full status act_runner || true
  echo
  echo "Wichtige Pfade:"
  echo "  Binary:  ${RUNNER_BINARY_PATH}"
  echo "  Symlink: ${RUNNER_COMPAT_SYMLINK_PATH}"
  echo "  Config:  ${RUNNER_CONFIG_FILE}"
  echo "  Home:    ${RUNNER_HOME}"
  echo
  echo "Beispiel mit direkter Registrierung:"
  echo "  sudo GITEA_INSTANCE_URL=https://gitea.example.tld GITEA_RUNNER_TOKEN=TOKEN ./install-gitea-runner.sh"
}

main() {
  require_root
  install_packages
  create_runner_user
  install_runner_binary
  generate_config
  register_runner
  install_service
  print_summary
}

main "$@"
