#!/usr/bin/env bash
# Mubisoft Linux Agent — Kurulum scripti
# Kullanım:
#   curl -fsSL https://releases.mubisoft.com/agent/linux/install.sh | sudo bash
#   bash install.sh [--token <AGENT_KEY_JWT>] [--name PROD-DB] [--no-systemd]
#
# Token verilmezse kurulum sonunda "mubisoft-agent setup" ile interaktif kurulum
# yapılır (önerilen yöntem — hata yapma şansı düşük).
#
# Bu script:
#   1. Bağımlılıkları kontrol eder (curl, libicu — .NET için)
#   2. Mevcut sürümü tespit eder, en son release'i GitHub Releases'tan indirir
#   3. /opt/mubisoft/bin altına kurar (mubisoft user)
#   4. systemd unit dosyasını yükler
#   5. Aktivasyon token'ı verildiyse register komutunu çalıştırır
#   6. Servisi başlatır

set -euo pipefail

# ─── Renkler ───────────────────────────────────────────────────────────
RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m'; CYAN='\033[0;36m'; BOLD='\033[1m'; NC='\033[0m'

info()  { echo -e "${CYAN}ℹ${NC}  $1"; }
ok()    { echo -e "${GREEN}✓${NC}  $1"; }
warn()  { echo -e "${YELLOW}⚠${NC}  $1"; }
err()   { echo -e "${RED}✗${NC}  $1" >&2; }

# ─── Sabitler ──────────────────────────────────────────────────────────
INSTALL_PREFIX="/opt/mubisoft"
BIN_DIR="${INSTALL_PREFIX}/bin"
CONFIG_DIR="/etc/mubisoft"
LOG_DIR="/var/log/mubisoft"
DATA_DIR="/var/lib/mubisoft"
SERVICE_USER="mubisoft"
SERVICE_NAME="mubisoft-agent"
SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}.service"
# Release dosyaları doğrudan R2'den indirilir; GitHub repo private olduğu için
# Releases API kullanılmaz. MUBI_RELEASES_URL ile self-hosted CDN override edilebilir.
RELEASES_URL="${MUBI_RELEASES_URL:-https://releases.mubisoft.com/agent/linux}"

# ─── Argüman parse ─────────────────────────────────────────────────────
TOKEN=""
AGENT_NAME=""
NO_SYSTEMD=0
RELAY_URL="${MUBI_RELAY_URL:-wss://relay.mubisoft.com}"
API_URL="${MUBI_API_URL:-https://api.mubisoft.com/api}"

while [[ $# -gt 0 ]]; do
  case "$1" in
    --token|-t) TOKEN="$2"; shift 2 ;;
    --name|-n) AGENT_NAME="$2"; shift 2 ;;
    --relay) RELAY_URL="$2"; shift 2 ;;
    --api) API_URL="$2"; shift 2 ;;
    --no-systemd) NO_SYSTEMD=1; shift ;;
    -h|--help)
      cat <<EOF
Mubisoft Linux Agent kurulum scripti

Kullanım:
  bash install.sh [--token <AGENT_KEY>] [--name PROD-DB] [--no-systemd]

Seçenekler:
  --token, -t   Web panel → Agent'lar → "Yeni Anahtar Oluştur" ile aldığınız
                uzun JWT. Sonradan da girilebilir.
  --name, -n    Agent adı (default: hostname)
  --relay       Relay URL (default: wss://relay.mubisoft.com)
  --api         API URL (default: https://api.mubisoft.com/api)
  --no-systemd  systemd servisi olarak kurma (manuel başlatma)

Önerilen — interaktif kurulum (renkli adım adım):
  sudo /opt/mubisoft/bin/mubisoft-agent setup

Tek komutla aktivasyon:
  sudo /opt/mubisoft/bin/mubisoft-agent register --token <AGENT_KEY>

Bağlantı profili ekleme:
  sudo -u mubisoft /opt/mubisoft/bin/mubisoft-agent profiles add \\
    --name accounting --driver mssql --connection-string '...'
EOF
      exit 0
      ;;
    *) err "Bilinmeyen argüman: $1"; exit 1 ;;
  esac
done

# ─── Root kontrolü ─────────────────────────────────────────────────────
if [[ $EUID -ne 0 ]]; then
  err "Bu scripti root olarak çalıştırın: sudo bash install.sh"
  exit 1
fi

# ─── Platform tespit ───────────────────────────────────────────────────
ARCH=$(uname -m)
case "$ARCH" in
  x86_64) RID="linux-x64" ;;
  aarch64|arm64) RID="linux-arm64" ;;
  *) err "Desteklenmeyen mimari: $ARCH"; exit 1 ;;
esac

if [[ ! -f /etc/os-release ]]; then
  err "/etc/os-release bulunamadı — Linux dağıtımı tespit edilemedi"
  exit 1
fi
. /etc/os-release
info "Sistem: ${PRETTY_NAME:-$NAME} ($ARCH → $RID)"

# ─── Bağımlılıklar ─────────────────────────────────────────────────────
need_pkg=()
command -v curl >/dev/null 2>&1 || need_pkg+=("curl")
command -v tar  >/dev/null 2>&1 || need_pkg+=("tar")

if [[ ${#need_pkg[@]} -gt 0 ]]; then
  info "Eksik paketler kuruluyor: ${need_pkg[*]}"
  if command -v apt-get >/dev/null 2>&1; then
    apt-get update -qq && apt-get install -y "${need_pkg[@]}"
  elif command -v dnf >/dev/null 2>&1; then
    dnf install -y "${need_pkg[@]}"
  elif command -v yum >/dev/null 2>&1; then
    yum install -y "${need_pkg[@]}"
  elif command -v apk >/dev/null 2>&1; then
    apk add --no-cache "${need_pkg[@]}"
  else
    err "Paket yöneticisi tespit edilemedi. Manuel kurun: ${need_pkg[*]}"
    exit 1
  fi
fi

# .NET 8 self-contained binary için libicu gerekir (UTF-8/zaman dilimi)
if command -v apt-get >/dev/null 2>&1; then
  if ! dpkg -l libicu* 2>/dev/null | grep -q '^ii'; then
    info "libicu kuruluyor (.NET runtime için)"
    apt-get install -y libicu-dev || apt-get install -y libicu70 || apt-get install -y libicu71 || true
  fi
fi

# ─── Headless Chromium bağımlılıkları (WhatsApp Web entegrasyonu) ──────
# Playwright Chromium ~150MB. Eksikse WA özellikleri çalışmaz ama agent'ın
# sorgu/yedek özellikleri etkilenmez (graceful degrade).
# MUBI_SKIP_CHROMIUM=1 ile atlanabilir (sunucuda WhatsApp gerek yoksa).
if [[ "${MUBI_SKIP_CHROMIUM:-0}" != "1" ]]; then
  info "WhatsApp Web için Chromium bağımlılıkları kuruluyor..."
  if command -v apt-get >/dev/null 2>&1; then
    # Debian/Ubuntu — Playwright'ın resmi listesi
    apt-get install -y --no-install-recommends \
      libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
      libdbus-1-3 libxkbcommon0 libatspi2.0-0 libx11-6 libxcomposite1 \
      libxdamage1 libxext6 libxfixes3 libxrandr2 libgbm1 libpango-1.0-0 \
      libcairo2 libasound2 libasound2t64 fonts-liberation 2>/dev/null || \
    apt-get install -y --no-install-recommends \
      libnss3 libnspr4 libatk1.0-0 libatk-bridge2.0-0 libcups2 libdrm2 \
      libdbus-1-3 libxkbcommon0 libatspi2.0-0 libx11-6 libxcomposite1 \
      libxdamage1 libxext6 libxfixes3 libxrandr2 libgbm1 libpango-1.0-0 \
      libcairo2 fonts-liberation || \
    warn "Bazı Chromium bağımlılıkları yüklenemedi — WhatsApp Web çalışmayabilir"
  elif command -v dnf >/dev/null 2>&1; then
    dnf install -y nss nspr atk at-spi2-atk cups-libs libdrm libxkbcommon \
      at-spi2-core libX11 libXcomposite libXdamage libXext libXfixes libXrandr \
      mesa-libgbm pango cairo alsa-lib liberation-fonts || \
    warn "Bazı Chromium bağımlılıkları yüklenemedi — WhatsApp Web çalışmayabilir"
  elif command -v apk >/dev/null 2>&1; then
    # Alpine — minimal set
    apk add --no-cache nss freetype harfbuzz ca-certificates ttf-freefont \
      chromium 2>/dev/null || warn "Alpine Chromium meta paketi yüklenemedi"
  else
    warn "Paket yöneticisi tespit edilemedi — Chromium bağımlılıkları manuel kurun"
  fi
  ok "Chromium bağımlılıkları tamam"
fi

# ─── Service user oluştur ──────────────────────────────────────────────
if ! id "$SERVICE_USER" >/dev/null 2>&1; then
  info "Servis kullanıcısı oluşturuluyor: $SERVICE_USER"
  useradd --system --shell /usr/sbin/nologin --home-dir "$DATA_DIR" --create-home "$SERVICE_USER"
  ok "Kullanıcı oluşturuldu"
fi

# ─── Dizin yapısı ──────────────────────────────────────────────────────
mkdir -p "$BIN_DIR" "$CONFIG_DIR" "$LOG_DIR" "$DATA_DIR"
chown -R "$SERVICE_USER:$SERVICE_USER" "$CONFIG_DIR" "$LOG_DIR" "$DATA_DIR"
chmod 750 "$CONFIG_DIR" "$LOG_DIR" "$DATA_DIR"

# ─── Binary indir ──────────────────────────────────────────────────────
info "En son sürüm tespit ediliyor..."
LATEST_TAG=$(curl -fsSL "${RELEASES_URL}/latest.txt" 2>/dev/null | tr -d '[:space:]' || echo "")

if [[ -z "$LATEST_TAG" ]]; then
  err "Sürüm bilgisi alınamadı: ${RELEASES_URL}/latest.txt"
  err "Manuel kurulum: binary'yi indirip ${BIN_DIR}/mubisoft-agent olarak yerleştirin"
  exit 1
fi

ASSET_NAME="mubisoft-agent-${LATEST_TAG}-${RID}.tar.gz"
# Versioned arşiv: agent/linux/v1.0.0/mubisoft-agent-v1.0.0-linux-x64.tar.gz
DOWNLOAD_URL="${RELEASES_URL}/${LATEST_TAG}/${ASSET_NAME}"
info "İndiriliyor: $ASSET_NAME (sürüm: ${LATEST_TAG})"

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

if ! curl -fsSL -o "$TMPDIR/${ASSET_NAME}" "$DOWNLOAD_URL"; then
  err "İndirme başarısız: $DOWNLOAD_URL"
  exit 1
fi

# ─── SHA256 doğrulama (zorunlu) ────────────────────────────────────────
# Supply-chain güvenliği için bu adım atlanmaz. Geliştirme/staging için
# MUBI_SKIP_SHA256=1 env var ile devre dışı bırakılabilir (önerilmez).
if ! command -v sha256sum >/dev/null 2>&1; then
  err "sha256sum komutu bulunamadı (coreutils paketi gerekli)"
  exit 1
fi

SHA_URL="${DOWNLOAD_URL}.sha256"
if [[ "${MUBI_SKIP_SHA256:-0}" == "1" ]]; then
  warn "SHA256 doğrulama atlandı (MUBI_SKIP_SHA256=1) — production'da KULLANMAYIN"
elif curl -fsSL -o "$TMPDIR/${ASSET_NAME}.sha256" "$SHA_URL" 2>/dev/null; then
  info "SHA256 doğrulanıyor..."
  (cd "$TMPDIR" && sha256sum -c "${ASSET_NAME}.sha256") || { err "SHA256 uyumsuz! Binary tampered olabilir."; exit 1; }
  ok "SHA256 doğrulandı"
else
  err "SHA256 dosyası indirilemedi: $SHA_URL"
  err "Bu kurulum güvenli değil — release sunucusunda hash dosyası eksik."
  err "Yine de devam etmek için: MUBI_SKIP_SHA256=1 (önerilmez, sadece dev/staging için)"
  exit 1
fi

# ─── Çıkar + yerleştir ─────────────────────────────────────────────────
info "Kuruluyor: $BIN_DIR"
tar -xzf "$TMPDIR/${ASSET_NAME}" -C "$BIN_DIR"
chmod +x "$BIN_DIR/mubisoft-agent"
chown -R "$SERVICE_USER:$SERVICE_USER" "$INSTALL_PREFIX"
ok "Binary kuruldu: $BIN_DIR/mubisoft-agent"

# Sistem PATH'inde olsun ki kullanıcı "mubisoft-agent ..." diye direkt çalıştırabilsin
ln -sf "$BIN_DIR/mubisoft-agent" /usr/local/bin/mubisoft-agent
ok "Sembolik link: /usr/local/bin/mubisoft-agent"

# ─── Playwright Chromium binary çek ────────────────────────────────────
# Microsoft.Playwright .NET, ilk InitializeAsync çağrısında Chromium yoksa hata
# verir. Burada servis kullanıcısı altında önceden indir ki ilk WA isteği
# anında çalışsın. PLAYWRIGHT_BROWSERS_PATH ile sistem-wide path kullanıyoruz
# → /opt/mubisoft/playwright-browsers (servis kullanıcısı okuyabilir).
if [[ "${MUBI_SKIP_CHROMIUM:-0}" != "1" ]]; then
  PLAYWRIGHT_BROWSERS_DIR="${INSTALL_PREFIX}/playwright-browsers"
  mkdir -p "$PLAYWRIGHT_BROWSERS_DIR"
  chown -R "$SERVICE_USER:$SERVICE_USER" "$PLAYWRIGHT_BROWSERS_DIR"

  # playwright.ps1 (cross-platform .ps1 → pwsh ile çalışır) ya da playwright.sh
  # `mubisoft-agent` self-contained olduğu için Playwright CLI da içinde bundled:
  # binary `playwright install chromium` komutunu environment'la çalıştırabilir.
  info "Chromium binary indiriliyor (~150MB)..."
  if PLAYWRIGHT_BROWSERS_PATH="$PLAYWRIGHT_BROWSERS_DIR" \
     "$BIN_DIR/mubisoft-agent" playwright install chromium 2>/dev/null; then
    chown -R "$SERVICE_USER:$SERVICE_USER" "$PLAYWRIGHT_BROWSERS_DIR"
    ok "Chromium binary kuruldu: $PLAYWRIGHT_BROWSERS_DIR"
  else
    # Bundled CLI yoksa direkt URL ile çekiyoruz. Bu fallback Playwright .NET
    # davranışını taklit eder: cache dizini → ilk InitializeAsync zaten indirir.
    warn "Bundled Playwright CLI çağrısı başarısız — Chromium ilk WA isteğinde otomatik inecek"
    warn "Manuel kurulum: sudo -u $SERVICE_USER PLAYWRIGHT_BROWSERS_PATH=$PLAYWRIGHT_BROWSERS_DIR $BIN_DIR/mubisoft-agent playwright install chromium"
  fi
fi

# ─── systemd unit ──────────────────────────────────────────────────────
if [[ $NO_SYSTEMD -eq 0 ]] && command -v systemctl >/dev/null 2>&1; then
  info "systemd unit yükleniyor"
  cat > "$SERVICE_FILE" <<'UNIT'
[Unit]
Description=Mubisoft Linux Agent
Documentation=https://mubisoft.com/docs
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/opt/mubisoft/bin/mubisoft-agent run
Restart=on-failure
RestartSec=10
StartLimitIntervalSec=300
StartLimitBurst=5

User=mubisoft
Group=mubisoft
WorkingDirectory=/opt/mubisoft

Environment=HOME=/var/lib/mubisoft
Environment=XDG_CONFIG_HOME=/etc/mubisoft
Environment=XDG_STATE_HOME=/var/log
# Playwright Chromium binary'si (install.sh tarafından önceden indirildi)
Environment=PLAYWRIGHT_BROWSERS_PATH=/opt/mubisoft/playwright-browsers

StandardOutput=journal
StandardError=journal
SyslogIdentifier=mubisoft-agent

NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/etc/mubisoft /var/log/mubisoft /var/lib/mubisoft
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
RestrictNamespaces=true
RestrictRealtime=true
RestrictSUIDSGID=true
LockPersonality=true

[Install]
WantedBy=multi-user.target
UNIT

  systemctl daemon-reload
  systemctl enable "$SERVICE_NAME"
  ok "systemd unit yüklendi: $SERVICE_FILE"

  # ─── Auto-update timer ─────────────────────────────────────────────
  # Günlük auto-update kontrolü (Squirrel benzeri) — install.sh idempotent
  # olduğu için aynı sürüm yüklüyse no-op, yeni sürüm varsa SHA256 doğrulayarak
  # swap eder. Random 0-6 saat jitter ile thundering herd önlenir.
  UPDATE_SERVICE_FILE="/etc/systemd/system/${SERVICE_NAME}-update.service"
  UPDATE_TIMER_FILE="/etc/systemd/system/${SERVICE_NAME}-update.timer"

  cat > "$UPDATE_SERVICE_FILE" <<UPDATE_UNIT
[Unit]
Description=Mubisoft Linux Agent — Auto-update kontrolü
After=network-online.target
Wants=network-online.target
ConditionPathExists=/opt/mubisoft/bin/mubisoft-agent

[Service]
Type=oneshot
ExecStart=/bin/bash -c 'curl -fsSL "\${MUBI_RELEASES_URL:-${RELEASES_URL}}/install.sh" | bash'
TimeoutStartSec=300
StandardOutput=journal
StandardError=journal
SyslogIdentifier=${SERVICE_NAME}-update
NoNewPrivileges=true
PrivateTmp=true
ProtectSystem=strict
ProtectHome=true
ReadWritePaths=/opt/mubisoft /etc/mubisoft /var/log/mubisoft
UPDATE_UNIT

  cat > "$UPDATE_TIMER_FILE" <<'UPDATE_TIMER'
[Unit]
Description=Mubisoft Linux Agent — Günlük auto-update kontrolü

[Timer]
OnBootSec=10min
OnUnitActiveSec=24h
RandomizedDelaySec=6h
Persistent=true

[Install]
WantedBy=timers.target
UPDATE_TIMER

  systemctl daemon-reload
  systemctl enable --now "${SERVICE_NAME}-update.timer"
  ok "Auto-update timer aktif (24sa + 0-6sa jitter): ${SERVICE_NAME}-update.timer"
fi

# ─── Aktivasyon ────────────────────────────────────────────────────────
if [[ -n "$TOKEN" ]]; then
  info "Aktivasyon yapılıyor..."
  AGENT_NAME="${AGENT_NAME:-$(hostname)}"
  sudo -u "$SERVICE_USER" \
    HOME="$DATA_DIR" XDG_CONFIG_HOME="$CONFIG_DIR" XDG_STATE_HOME="$LOG_DIR" \
    "$BIN_DIR/mubisoft-agent" register \
      --token "$TOKEN" \
      --name "$AGENT_NAME" \
      --relay "$RELAY_URL" \
      --api "$API_URL"
  ok "Aktivasyon tamamlandı"
fi

# ─── Servisi başlat / yeniden başlat ───────────────────────────────────
# İki senaryo:
#   1. İlk kurulum + token → servis ilk kez başlatılır
#   2. Auto-update timer çağrısı (token yok, servis önceden enabled) → binary
#      swap olduğu için yeni sürümü çalıştırmak üzere try-restart edilir
if [[ $NO_SYSTEMD -eq 0 ]] && command -v systemctl >/dev/null 2>&1; then
  if [[ -n "$TOKEN" ]]; then
    info "Servis başlatılıyor"
    systemctl restart "$SERVICE_NAME"
    sleep 2
    if systemctl is-active --quiet "$SERVICE_NAME"; then
      ok "Servis çalışıyor"
    else
      warn "Servis başlamadı. Log: journalctl -u $SERVICE_NAME -n 50"
    fi
  elif systemctl is-enabled --quiet "$SERVICE_NAME" 2>/dev/null; then
    # Auto-update path — servis zaten kayıtlı, sadece yeni binary'yi yükle
    info "Mevcut servis için yeniden başlatma (auto-update)"
    systemctl try-restart "$SERVICE_NAME" || warn "try-restart başarısız"
  fi
fi

# ─── Özet ──────────────────────────────────────────────────────────────
# Not: /usr/local/bin/mubisoft-agent symlink'i sayesinde tüm komutlar kısa
# isimle çalıştırılabilir — uzun path (/opt/mubisoft/bin/...) gerek değil.
echo ""
echo -e "${BOLD}Kurulum tamamlandı.${NC}"
echo ""
echo "  Yapılandırma:    $CONFIG_DIR"
echo "  Loglar:          $LOG_DIR"
echo "  Binary:          $BIN_DIR/mubisoft-agent"
echo "  Komut (PATH):    /usr/local/bin/mubisoft-agent → mubisoft-agent"
[[ $NO_SYSTEMD -eq 0 ]] && echo "  Servis:          $SERVICE_NAME"
echo ""

if [[ -z "$TOKEN" ]]; then
  echo -e "${YELLOW}Sıradaki adım — kurulumu tamamlayın:${NC}"
  echo ""
  echo -e "  ${BOLD}İnteraktif kurulum (önerilen):${NC}"
  echo "    sudo mubisoft-agent setup"
  echo ""
  echo -e "  ${BOLD}Veya tek komutla:${NC}"
  echo "    sudo mubisoft-agent register --token <AGENT_KEY> --name $(hostname)"
  echo ""
  echo "  Anahtarı şuradan alabilirsiniz: https://app.mubisoft.com → Agent'lar → Yeni Anahtar Oluştur"
  echo ""
fi

cat <<EOF
Yararlı komutlar:
  sudo mubisoft-agent setup                      # İnteraktif kurulum sihirbazı
  sudo mubisoft-agent status                     # Durum + lisans + profiller
  sudo mubisoft-agent profiles list              # Profil listesi
  sudo mubisoft-agent profiles add ...           # Yeni profil ekle
  sudo mubisoft-agent profiles test --name X     # Profile bağlantı testi
  sudo mubisoft-agent logs --follow              # Canlı log akışı
  sudo mubisoft-agent --version                  # Sürüm bilgisi

Servis yönetimi:
  sudo mubisoft-agent service start              # Servisi başlat
  sudo mubisoft-agent service stop               # Servisi durdur
  sudo mubisoft-agent service restart            # Yeniden başlat
  sudo mubisoft-agent service status             # Servis durumu
  sudo mubisoft-agent service enable             # Boot'ta otomatik başlat

Kaldırma:
  sudo mubisoft-agent uninstall                  # Tamamen kaldır
  sudo mubisoft-agent uninstall --keep-data      # Yapılandırmayı koru

systemctl ile (alternatif):
  systemctl status mubisoft-agent
  systemctl restart mubisoft-agent
  journalctl -u mubisoft-agent -f

Sorun yaşarsanız: https://mubisoft.com/dokumantasyon.html#kurulum-linux
EOF
