#!/bin/bash
# ===========================================================================
# meyton-sync Source — Installations-Skript
# Unterstützte Systeme: openSUSE / SLES, Debian, Ubuntu
# Muss als root ausgeführt werden.
# ===========================================================================
set -euo pipefail

# ---------------------------------------------------------------------------
# Hilfsfunktionen
# ---------------------------------------------------------------------------

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

err()     { echo -e "${RED}FEHLER: $*${NC}" >&2; exit 1; }
info()    { echo -e "${GREEN}[OK]${NC} $*"; }
warn()    { echo -e "${YELLOW}[WARN]${NC} $*"; }
section() { echo; echo -e "${CYAN}${BOLD}=== $* ===${NC}"; echo; }

ask() {
    # /dev/tty nötig: Funktion wird via $() aufgerufen,
    # stdout ist captured — Prompt und read müssen direkt ans Terminal.
    local label="$1" default="$2"
    echo -ne "  $label [$default]: " > /dev/tty
    read -r _INPUT < /dev/tty
    echo "${_INPUT:-$default}"
}

ask_secret() {
    local label="$1" default="$2"
    echo -ne "  $label [$default]: " > /dev/tty
    read -rs _INPUT < /dev/tty
    echo > /dev/tty
    echo "${_INPUT:-$default}"
}

# ---------------------------------------------------------------------------
# Voraussetzungen prüfen
# ---------------------------------------------------------------------------

[ "$(id -u)" -eq 0 ] || err "Dieses Skript muss als root ausgeführt werden."

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"

[ -f "$SCRIPT_DIR/source.py" ] || \
    err "source.py nicht gefunden. Skript muss aus dem source/-Verzeichnis ausgeführt werden."

# ---------------------------------------------------------------------------
# Betriebssystem erkennen
# ---------------------------------------------------------------------------

# shellcheck source=/dev/null
. /etc/os-release
OS_ID="${ID:-unknown}"
OS_LIKE="${ID_LIKE:-}"

if   [[ "$OS_ID" == opensuse* ]] || [[ "$OS_LIKE" == *suse* ]] || [[ "$OS_ID" == sles* ]]; then
    OS_TYPE="suse"
elif [[ "$OS_ID" == "ubuntu" ]] || [[ "$OS_ID" == "debian" ]] || [[ "$OS_LIKE" == *debian* ]]; then
    OS_TYPE="debian"
else
    err "Nicht unterstütztes Betriebssystem: $OS_ID\n  Unterstützt: openSUSE, SLES, Debian, Ubuntu"
fi

# ---------------------------------------------------------------------------
# Aktuelle Konfigurationswerte als Defaults lesen
# ---------------------------------------------------------------------------

conf_val() {
    # conf_val <schluessel> <fallback>
    local key="$1" fallback="$2"
    local val
    val=$(grep -E "^${key}\s*=" "$SCRIPT_DIR/source.conf" 2>/dev/null \
          | head -1 | sed 's/^[^=]*=\s*//' | tr -d '\r')
    echo "${val:-$fallback}"
}

DEF_DB_HOST=$(conf_val "host"         "192.168.10.200")
DEF_DB_PORT=$(conf_val "port"         "3306")
DEF_DB_USER=$(conf_val "user"         "meyton")
DEF_DB_PASS=$(conf_val "password"     "mc4hct")
DEF_DB_NAME=$(conf_val "database"     "SSMDB2")
DEF_TARGET_URL=$(conf_val "target_url"   "https://www.mydomain.de/meyton/sync")
DEF_OWN_TOKEN=$(conf_val "own_token"    \
    "$(python3 -c 'import secrets; print(secrets.token_hex(32))')")
DEF_TARGET_TOKEN=$(conf_val "target_token" \
    "$(python3 -c 'import secrets; print(secrets.token_hex(32))')")
DEF_INTERVAL=$(conf_val "interval"    "60")
DEF_STANDS=$(conf_val  "stands"      "10")
DEF_BATCH=$(conf_val   "batch_size"  "100")

# ---------------------------------------------------------------------------
# Konfiguration interaktiv abfragen
# ---------------------------------------------------------------------------

section "meyton-sync Source — Installation"
echo "  System  : $PRETTY_NAME"
echo "  OS-Typ  : $OS_TYPE"
echo
echo "  Alle Standardwerte können mit Enter übernommen werden."
echo "  Passwörter werden nicht angezeigt während der Eingabe."

section "Datenbankverbindung (SSMDB2 auf der Schützenanlage)"
DB_HOST=$(ask        "Host"       "$DEF_DB_HOST")
DB_PORT=$(ask        "Port"       "$DEF_DB_PORT")
DB_USER=$(ask        "User"       "$DEF_DB_USER")
DB_PASS=$(ask_secret "Passwort"   "$DEF_DB_PASS")
DB_NAME=$(ask        "Datenbank"  "$DEF_DB_NAME")

section "Synchronisierung"
TARGET_URL=$(ask    "Ziel-URL des Target-Servers"  "$DEF_TARGET_URL")
echo
echo "  Die folgenden Tokens müssen mit der Target-Konfiguration übereinstimmen:"
OWN_TOKEN=$(ask    "  Eigener Token (Source)"       "$DEF_OWN_TOKEN")
TARGET_TOKEN=$(ask "  Token des Target-Servers"     "$DEF_TARGET_TOKEN")
echo
INTERVAL=$(ask  "Sync-Intervall in Sekunden (1-600)" "$DEF_INTERVAL")
STANDS=$(ask    "Anzahl der Schiessstände"            "$DEF_STANDS")
BATCH=$(ask     "Scheiben pro Übertragungspaket"      "$DEF_BATCH")

# ---------------------------------------------------------------------------
# Zusammenfassung und Bestätigung
# ---------------------------------------------------------------------------

section "Zusammenfassung"
echo "  Datenbank    : $DB_USER@$DB_HOST:$DB_PORT/$DB_NAME"
echo "  Ziel-URL     : $TARGET_URL"
echo "  Intervall    : ${INTERVAL}s  |  Stände: $STANDS"
echo "  Installiert  : /opt/meyton-sync/source/"
echo
read -rp "Installation starten? [J/n]: " _CONFIRM
[[ "${_CONFIRM,,}" == "n" ]] && { echo "Abgebrochen."; exit 0; }

# ---------------------------------------------------------------------------
# Pakete installieren
# ---------------------------------------------------------------------------

section "Pakete installieren"

if [ "$OS_TYPE" = "suse" ]; then
    info "Installiere via zypper..."
    zypper install -y python3 python3-pip python3-requests

    info "Installiere Python-Pakete via pip3..."
    # Versuche zuerst ohne Flag, dann mit --break-system-packages (Python >= 3.11)
    pip3 install PyMySQL apscheduler 2>/dev/null || \
    pip3 install --break-system-packages PyMySQL apscheduler
else
    info "Installiere via apt-get..."
    apt-get update -q
    apt-get install -y \
        python3 \
        python3-pymysql \
        python3-requests \
        python3-apscheduler
fi

info "Pakete installiert."

# ---------------------------------------------------------------------------
# System-User anlegen
# ---------------------------------------------------------------------------

section "System-User anlegen"

if ! getent group meyton-sync &>/dev/null; then
    groupadd --system meyton-sync
    info "System-Gruppe 'meyton-sync' angelegt."
else
    info "System-Gruppe 'meyton-sync' bereits vorhanden."
fi

if ! id meyton-sync &>/dev/null; then
    useradd --system --no-create-home --shell /usr/sbin/nologin -g meyton-sync meyton-sync
    info "System-User 'meyton-sync' angelegt."
else
    info "System-User 'meyton-sync' bereits vorhanden."
fi

# ---------------------------------------------------------------------------
# Dateien installieren
# ---------------------------------------------------------------------------

section "Dateien installieren"

INSTALL_DIR="/opt/meyton-sync/source"
mkdir -p "$INSTALL_DIR"

# Bestehende Konfiguration sichern
if [ -f "$INSTALL_DIR/source.conf" ]; then
    cp "$INSTALL_DIR/source.conf" "$INSTALL_DIR/source.conf.bak"
    warn "Bestehende Konfiguration gesichert: source.conf.bak"
fi

cp "$SCRIPT_DIR/source.py" "$INSTALL_DIR/"
info "source.py kopiert nach $INSTALL_DIR"

# ---------------------------------------------------------------------------
# Konfigurationsdatei schreiben
# ---------------------------------------------------------------------------

cat > "$INSTALL_DIR/source.conf" << EOF
[database]
host = ${DB_HOST}
port = ${DB_PORT}
user = ${DB_USER}
password = ${DB_PASS}
database = ${DB_NAME}

[sync]
target_url = ${TARGET_URL}
own_token = ${OWN_TOKEN}
target_token = ${TARGET_TOKEN}
; Intervall in Sekunden (1-600), Default: 60
interval = ${INTERVAL}
; Anzahl der Schiessstände (zum Berechnen des Abfrage-Limits)
stands = ${STANDS}
; Anzahl Scheiben pro Übertragungspaket
batch_size = ${BATCH}
; Timeout für HTTP-Anfragen in Sekunden
request_timeout = 30

[logging]
level = INFO
file = source.log
EOF

info "source.conf geschrieben."

# ---------------------------------------------------------------------------
# Berechtigungen setzen
# ---------------------------------------------------------------------------

chown -R meyton-sync:meyton-sync "$INSTALL_DIR"
chmod 750 "$INSTALL_DIR"
chmod 640 "$INSTALL_DIR/source.conf"
chmod 750 "$INSTALL_DIR/source.py"
info "Berechtigungen gesetzt (owner: meyton-sync)."

# ---------------------------------------------------------------------------
# Systemd-Service installieren
# ---------------------------------------------------------------------------

section "Systemd-Service installieren"

# Python-Pfad ermitteln
PYTHON_BIN=$(which python3)

cat > /etc/systemd/system/meyton-sync-source.service << EOF
[Unit]
Description=meyton-sync Source (Sync-Daemon)
After=network.target mariadb.service mysql.service
Wants=mariadb.service mysql.service

[Service]
Type=simple
User=meyton-sync
Group=meyton-sync
WorkingDirectory=${INSTALL_DIR}

ExecStart=${PYTHON_BIN} ${INSTALL_DIR}/source.py

Restart=on-failure
RestartSec=10

StandardOutput=journal
StandardError=journal
SyslogIdentifier=meyton-sync-source

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable meyton-sync-source

# Service (neu-)starten
if systemctl is-active --quiet meyton-sync-source; then
    systemctl restart meyton-sync-source
    info "Service neu gestartet."
else
    systemctl start meyton-sync-source
    info "Service gestartet."
fi

# ---------------------------------------------------------------------------
# Abschluss
# ---------------------------------------------------------------------------

section "Installation erfolgreich abgeschlossen"
echo -e "  ${BOLD}Installationsverzeichnis${NC}  : $INSTALL_DIR"
echo -e "  ${BOLD}Konfigurationsdatei${NC}       : $INSTALL_DIR/source.conf"
echo -e "  ${BOLD}Service-Status${NC}            : $(systemctl is-active meyton-sync-source)"
echo
echo "  Logs anzeigen:"
echo "    journalctl -u meyton-sync-source -f"
echo
echo "  Service steuern:"
echo "    systemctl start|stop|restart|status meyton-sync-source"
echo
