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

FEDEO_REF="${FEDEO_REF:-dev}"
FEDEO_RAW_BASE_URL="${FEDEO_RAW_BASE_URL:-https://git.federspiel.tech/flfeders/FEDEO/raw/branch/${FEDEO_REF}}"
FEDEO_DIR="${FEDEO_DIR:-/opt/fedeo}"
SETUP_ARGS=("$@")
FEDEO_USE_SUDO_DOCKER="${FEDEO_USE_SUDO_DOCKER:-false}"
TTY_INPUT="${FEDEO_TTY_INPUT:-/dev/tty}"
TTY_FD=""

if { exec 3<"$TTY_INPUT"; } 2>/dev/null; then
  TTY_FD="3"
fi

SUDO=""
if [[ "$(id -u)" -ne 0 ]]; then
  if command -v sudo >/dev/null 2>&1; then
    SUDO="sudo"
  fi
fi

usage() {
  cat <<'USAGE'
FEDEO Selfhost Installer

Typischer One-Liner:
  curl -fsSL https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev/scripts/selfhost-install.sh | bash

Mit Optionen für den Setup-Assistenten:
  curl -fsSL https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev/scripts/selfhost-install.sh | bash -s -- --simple --start
  curl -fsSL https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev/scripts/selfhost-install.sh | bash -s -- --advanced

Umgebung:
  FEDEO_DIR=/opt/fedeo
  FEDEO_REF=dev
  FEDEO_RAW_BASE_URL=https://git.federspiel.tech/flfeders/FEDEO/raw/branch/dev
USAGE
}

read_interactive() {
  if [[ -n "$TTY_FD" ]]; then
    read -u "$TTY_FD" "$@"
  else
    read "$@"
  fi
}

yes_no() {
  local label="$1"
  local default_value="${2:-j}"
  local answer

  while true; do
    read_interactive -r -p "$label [$default_value]: " answer
    answer="${answer:-$default_value}"
    case "$answer" in
      y|Y|j|J|yes|Yes|ja|Ja)
        return 0
        ;;
      n|N|no|No|nein|Nein)
        return 1
        ;;
      *)
        echo "Bitte ja oder nein eingeben."
        ;;
    esac
  done
}

have() {
  command -v "$1" >/dev/null 2>&1
}

install_base_packages() {
  local missing=()
  for binary in curl openssl; do
    if ! have "$binary"; then
      missing+=("$binary")
    fi
  done

  if [[ "${#missing[@]}" -eq 0 ]]; then
    return
  fi

  if ! have apt-get; then
    echo "Fehlende Programme: ${missing[*]}" >&2
    echo "Bitte installiere sie manuell und starte den Installer erneut." >&2
    exit 1
  fi

  if [[ "$(id -u)" -ne 0 && -z "$SUDO" ]]; then
    echo "Fehlende Programme: ${missing[*]}" >&2
    echo "Ohne root oder sudo kann der Installer sie nicht automatisch installieren." >&2
    exit 1
  fi

  echo "Installiere Basispakete: ${missing[*]}"
  $SUDO apt-get update
  $SUDO apt-get install -y ca-certificates curl openssl
}

ensure_docker() {
  if have docker && docker compose version >/dev/null 2>&1; then
    FEDEO_USE_SUDO_DOCKER="false"
    return
  fi

  if [[ -n "$SUDO" ]] && have docker && $SUDO docker compose version >/dev/null 2>&1; then
    FEDEO_USE_SUDO_DOCKER="true"
    return
  fi

  echo
  echo "Docker Engine mit Compose Plugin wurde nicht gefunden."
  if ! have curl; then
    echo "curl fehlt, Docker kann nicht automatisch installiert werden." >&2
    exit 1
  fi

  if yes_no "Docker jetzt über das offizielle Docker-Installationsscript installieren?" "j"; then
    if [[ "$(id -u)" -ne 0 && -z "$SUDO" ]]; then
      echo "Ohne root oder sudo kann Docker nicht automatisch installiert werden." >&2
      exit 1
    fi
    curl -fsSL https://get.docker.com | $SUDO sh
  else
    echo "Bitte Docker Engine inkl. Compose Plugin installieren und den Installer erneut starten." >&2
    exit 1
  fi

  if docker compose version >/dev/null 2>&1; then
    FEDEO_USE_SUDO_DOCKER="false"
    return
  fi

  if [[ -n "$SUDO" ]] && $SUDO docker compose version >/dev/null 2>&1; then
    FEDEO_USE_SUDO_DOCKER="true"
    return
  fi

  if ! docker compose version >/dev/null 2>&1; then
    echo "Docker Compose ist nach der Installation noch nicht verfügbar." >&2
    echo "Melde dich ggf. neu an oder prüfe die Docker-Installation." >&2
    exit 1
  fi
}

download_file() {
  local source="$1"
  local target="$2"
  local temp_file="${target}.tmp"

  mkdir -p "$(dirname "$target")"
  curl -fsSL "$source" -o "$temp_file"
  mv "$temp_file" "$target"
}

download_selfhost_files() {
  echo
  echo "Zielverzeichnis: $FEDEO_DIR"
  echo "Quelle:          $FEDEO_RAW_BASE_URL"

  if ! mkdir -p "$FEDEO_DIR/scripts" 2>/dev/null; then
    if [[ -z "$SUDO" ]]; then
      echo "Keine Schreibrechte für $FEDEO_DIR und sudo ist nicht verfügbar." >&2
      exit 1
    fi
    $SUDO mkdir -p "$FEDEO_DIR/scripts"
    $SUDO chown "$(id -u):$(id -g)" "$FEDEO_DIR" "$FEDEO_DIR/scripts"
  fi

  if [[ -d "$FEDEO_DIR/.git" ]]; then
    echo "Hinweis: In $FEDEO_DIR liegt noch ein alter Git-Checkout. Der Installer aktualisiert nur die Selfhost-Dateien und lässt Daten, .env und Checkout unangetastet."
  fi

  echo "Lade Selfhost-Dateien..."
  download_file "$FEDEO_RAW_BASE_URL/docker-compose.selfhost.yml" "$FEDEO_DIR/docker-compose.yml"
  download_file "$FEDEO_RAW_BASE_URL/.env.example" "$FEDEO_DIR/.env.example"
  download_file "$FEDEO_RAW_BASE_URL/scripts/selfhost-setup.sh" "$FEDEO_DIR/scripts/selfhost-setup.sh"
  chmod +x "$FEDEO_DIR/scripts/selfhost-setup.sh"
}

main() {
  if [[ "${1:-}" == "--help" || "${1:-}" == "-h" ]]; then
    usage
    exit 0
  fi

  cat <<'EOF'
FEDEO Selfhost Installer

Dieser Installer bringt die typische Serverstruktur mit:
  - prüft Basispakete
  - installiert Docker optional automatisch
  - lädt nur die Selfhost-Dateien nach /opt/fedeo
  - startet danach den geführten Selfhost-Assistenten

EOF

  install_base_packages
  ensure_docker
  download_selfhost_files

  echo
  echo "Starte Selfhost-Assistent..."
  cd "$FEDEO_DIR"
  export FEDEO_USE_SUDO_DOCKER
  export FEDEO_TTY_INPUT="$TTY_INPUT"
  if [[ "$TTY_INPUT" == "/dev/tty" && -r "$TTY_INPUT" ]]; then
    exec bash scripts/selfhost-setup.sh "${SETUP_ARGS[@]}" <"$TTY_INPUT"
  fi
  exec bash scripts/selfhost-setup.sh "${SETUP_ARGS[@]}"
}

main "$@"
