#!/bin/bash

# MYP Backend Installations-Skript
# Dieses Skript installiert das Backend mit Docker und Host-Netzwerkanbindung

# Farbcodes für Ausgabe
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Funktion zur Ausgabe mit Zeitstempel
log() {
  echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $1"
}

error_log() {
  echo -e "${RED}[$(date +'%Y-%m-%d %H:%M:%S')] FEHLER:${NC} $1" >&2
}

# Funktion zum Bereinigen vorhandener Installationen
cleanup_existing_installation() {
  log "${YELLOW}Bereinige vorhandene Installation...${NC}"
  
  # Stoppe und entferne existierende Container
  if docker ps -a | grep -q "myp-backend"; then
    log "Stoppe und entferne existierenden Backend-Container..."
    docker stop myp-backend &>/dev/null || true
    docker rm myp-backend &>/dev/null || true
  fi
  
  # Entferne Docker Images
  if docker images | grep -q "myp-backend"; then
    log "Entferne existierendes Backend-Image..."
    docker rmi myp-backend &>/dev/null || true
  fi
  
  log "${GREEN}Bereinigung abgeschlossen.${NC}"
}

# Pfade definieren
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
BACKEND_DIR="$SCRIPT_DIR/backend"

# Prüfen ob Verzeichnis existiert
if [ ! -d "$BACKEND_DIR" ]; then
  error_log "Backend-Verzeichnis '$BACKEND_DIR' nicht gefunden."
  exit 1
fi

# Bereinige existierende Installation
cleanup_existing_installation

# Funktion zur Installation von Docker und Docker Compose für Raspberry Pi
install_docker() {
  log "${YELLOW}Docker ist nicht installiert. Installation wird gestartet...${NC}"
  
  # Erkenne Raspberry Pi
  if [ -f /proc/device-tree/model ] && grep -q "Raspberry Pi" /proc/device-tree/model; then
    log "${GREEN}Raspberry Pi erkannt. Installiere Docker für ARM-Architektur...${NC}"
    IS_RASPBERRY_PI=true
  else
    IS_RASPBERRY_PI=false
  fi
  
  # Aktualisiere Paketindex
  if ! sudo apt-get update; then
    error_log "Konnte Paketindex nicht aktualisieren. Bitte manuell installieren."
    exit 1
  fi
  
  # Installiere erforderliche Pakete
  if ! sudo apt-get install -y apt-transport-https ca-certificates curl gnupg software-properties-common; then
    error_log "Konnte erforderliche Pakete nicht installieren. Bitte manuell installieren."
    exit 1
  fi
  
  # Raspberry Pi-spezifische Installation
  if [ "$IS_RASPBERRY_PI" = true ]; then
    # Setze Systemarchitektur für Raspberry Pi (armhf oder arm64)
    ARCH=$(dpkg --print-architecture)
    log "Erkannte Systemarchitektur: ${ARCH}"
    
    # Installiere Docker mit convenience script (für Raspberry Pi empfohlen)
    log "${YELLOW}Installiere Docker mit dem convenience script...${NC}"
    curl -fsSL https://get.docker.com -o get-docker.sh
    sudo sh get-docker.sh
    
    if [ $? -ne 0 ]; then
      error_log "Docker-Installation fehlgeschlagen. Bitte manuell installieren."
      exit 1
    fi
  else
    # Standard-Installation für andere Systeme
    # Füge Docker's offiziellen GPG-Schlüssel hinzu
    curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
    
    # Füge Docker-Repository hinzu
    if ! sudo add-apt-repository "deb [arch=$(dpkg --print-architecture)] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable"; then
      error_log "Konnte Docker-Repository nicht hinzufügen. Prüfen Sie, ob Ihr System unterstützt wird."
      exit 1
    fi
    
    # Aktualisiere Paketindex erneut
    sudo apt-get update
    
    # Installiere Docker
    if ! sudo apt-get install -y docker-ce docker-ce-cli containerd.io; then
      error_log "Konnte Docker nicht installieren. Bitte manuell installieren."
      exit 1
    fi
  fi
  
  # Füge aktuellen Benutzer zur Docker-Gruppe hinzu
  sudo usermod -aG docker "$USER"
  
  log "${GREEN}Docker wurde installiert.${NC}"
  log "${YELLOW}WICHTIG: Möglicherweise müssen Sie sich neu anmelden, damit die Gruppenänderung wirksam wird.${NC}"
  
  # Prüfen, ob Docker Compose v2 Plugin verfügbar ist (bevorzugt, da moderner)
  log "${YELLOW}Prüfe Docker Compose Version...${NC}"
  
  if docker compose version &> /dev/null; then
    log "${GREEN}Docker Compose v2 Plugin ist bereits installiert.${NC}"
    DOCKER_COMPOSE_V2=true
  else
    log "${YELLOW}Docker Compose v2 Plugin nicht gefunden. Versuche Docker Compose v1 zu installieren...${NC}"
    DOCKER_COMPOSE_V2=false
    
    if [ "$IS_RASPBERRY_PI" = true ]; then
      # Für Raspberry Pi ist es besser, die richtige Architektur zu verwenden
      if [ "$ARCH" = "armhf" ]; then
        log "Installiere Docker Compose für armhf (32-bit)..."
        sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-armv7" -o /usr/local/bin/docker-compose
      elif [ "$ARCH" = "arm64" ]; then
        log "Installiere Docker Compose für arm64 (64-bit)..."
        sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-aarch64" -o /usr/local/bin/docker-compose
      else
        # Fallback auf v1.29.2 für unbekannte ARM-Architekturen
        log "Verwende automatische Architekturerkennung für Docker Compose v1.29.2..."
        sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
      fi
    else
      # Für andere Systeme versuche zuerst v2, dann v1.29.2 als Fallback
      log "Installiere Docker Compose v2 für $(uname -s)/$(uname -m)..."
      if ! sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose; then
        log "${YELLOW}Konnte Docker Compose v2 nicht herunterladen. Versuche v1.29.2...${NC}"
        sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
      fi
    fi
    
    if [ $? -ne 0 ]; then
      error_log "Konnte Docker Compose nicht herunterladen. Bitte manuell installieren."
      exit 1
    fi
    
    sudo chmod +x /usr/local/bin/docker-compose
    
    log "${GREEN}Docker Compose wurde installiert.${NC}"
  fi
  
  # Starte Docker-Dienst
  if command -v systemctl &> /dev/null; then
    sudo systemctl enable docker
    sudo systemctl start docker
  elif command -v service &> /dev/null; then
    sudo service docker enable
    sudo service docker start
  fi
}

# Prüfen ob Docker installiert ist
if ! command -v docker &> /dev/null; then
  log "${YELLOW}Docker ist nicht installiert.${NC}"
  read -p "Möchten Sie Docker installieren? (j/n): " install_docker_choice
  if [[ "$install_docker_choice" == "j" ]]; then
    install_docker
  else
    error_log "Docker wird für die Installation benötigt. Bitte installieren Sie Docker manuell."
    log "Siehe: https://docs.docker.com/get-docker/"
    exit 1
  fi
fi

# Prüfen ob Docker Daemon läuft
if ! docker info &> /dev/null; then
  log "${YELLOW}Docker-Daemon läuft nicht. Versuche, den Dienst zu starten...${NC}"
  
  # Versuche, Docker zu starten
  if command -v systemctl &> /dev/null; then
    sudo systemctl start docker
  elif command -v service &> /dev/null; then
    sudo service docker start
  else
    error_log "Konnte Docker-Daemon nicht starten. Bitte starten Sie den Docker-Dienst manuell."
    log "Starten mit: sudo systemctl start docker oder sudo service docker start"
    exit 1
  fi
  
  # Prüfe erneut, ob Docker läuft
  if ! docker info &> /dev/null; then
    error_log "Docker-Daemon konnte nicht gestartet werden. Bitte starten Sie den Docker-Dienst manuell."
    exit 1
  fi
  
  log "${GREEN}Docker-Daemon wurde erfolgreich gestartet.${NC}"
fi

# Prüfen ob Docker Compose installiert ist
if docker compose version &> /dev/null; then
  log "${GREEN}Docker Compose v2 Plugin ist bereits installiert.${NC}"
  DOCKER_COMPOSE_V2=true
elif command -v docker-compose &> /dev/null; then
  log "${GREEN}Docker Compose v1 ist bereits installiert.${NC}"
  DOCKER_COMPOSE_V2=false
else
  log "${YELLOW}Docker Compose ist nicht installiert.${NC}"
  DOCKER_COMPOSE_V2=false
  read -p "Möchten Sie Docker Compose installieren? (j/n): " install_compose_choice
  if [[ "$install_compose_choice" == "j" ]]; then
    log "${YELLOW}Installiere Docker Compose...${NC}"
    
    # Prüfe ob das Betriebssystem ARM-basiert ist (z.B. Raspberry Pi)
    if grep -q "arm" /proc/cpuinfo 2> /dev/null; then
      ARCH=$(dpkg --print-architecture 2> /dev/null || echo "unknown")
      IS_RASPBERRY_PI=true
    else 
      IS_RASPBERRY_PI=false
    fi
    
    # Versuche zuerst Docker Compose v2 zu installieren
    if [ "$IS_RASPBERRY_PI" = true ]; then
      if [ "$ARCH" = "armhf" ]; then
        log "Installiere Docker Compose für armhf (32-bit)..."
        sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-armv7" -o /usr/local/bin/docker-compose
      elif [ "$ARCH" = "arm64" ]; then
        log "Installiere Docker Compose für arm64 (64-bit)..."
        sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-linux-aarch64" -o /usr/local/bin/docker-compose
      else
        log "Verwende automatische Architekturerkennung für Docker Compose v1.29.2..."
        sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
      fi
    else
      log "Installiere Docker Compose v2 für $(uname -s)/$(uname -m)..."
      if ! sudo curl -L "https://github.com/docker/compose/releases/download/v2.6.1/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose; then
        log "${YELLOW}Konnte Docker Compose v2 nicht herunterladen. Versuche v1.29.2...${NC}"
        sudo curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
      fi
    fi
    
    if [ $? -ne 0 ]; then
      error_log "Konnte Docker Compose nicht herunterladen. Bitte manuell installieren."
      exit 1
    fi
    
    sudo chmod +x /usr/local/bin/docker-compose
    
    log "${GREEN}Docker Compose wurde installiert.${NC}"
  else
    error_log "Docker Compose wird für die Installation benötigt. Bitte installieren Sie es manuell."
    log "Siehe: https://docs.docker.com/compose/install/"
    exit 1
  fi
fi

# Prüfen ob wget installiert ist (wird für healthcheck verwendet)
if ! command -v wget &> /dev/null; then
  error_log "wget ist nicht installiert, wird aber für den Container-Healthcheck benötigt."
  log "Installation mit: sudo apt-get install wget"
  exit 1
fi

# Wechsle ins Backend-Verzeichnis
log "Wechsle ins Verzeichnis: $BACKEND_DIR"
cd "$BACKEND_DIR" || {
  error_log "Konnte nicht ins Verzeichnis $BACKEND_DIR wechseln."
  exit 1
}

# Prüfe ob Dockerfile existiert
if [ ! -f "Dockerfile" ]; then
  error_log "Dockerfile nicht gefunden in $BACKEND_DIR."
  exit 1
fi

# Prüfe ob docker-compose.yml existiert
if [ ! -f "docker-compose.yml" ]; then
  error_log "docker-compose.yml nicht gefunden in $BACKEND_DIR."
  exit 1
fi

# Erstelle .env-Datei
log "${YELLOW}Erstelle .env Datei...${NC}"
cat > .env << EOL
SECRET_KEY=7445630171969DFAC92C53CEC92E67A9CB2E00B3CB2F
DATABASE_PATH=instance/myp.db
TAPO_USERNAME=till.tomczak@mercedes-benz.com
TAPO_PASSWORD=744563017196A
PRINTERS={"Printer 1": {"ip": "192.168.0.100"}, "Printer 2": {"ip": "192.168.0.101"}, "Printer 3": {"ip": "192.168.0.102"}, "Printer 4": {"ip": "192.168.0.103"}, "Printer 5": {"ip": "192.168.0.104"}, "Printer 6": {"ip": "192.168.0.106"}}
EOL

if [ ! -f ".env" ]; then
  error_log "Konnte .env-Datei nicht erstellen. Prüfen Sie die Berechtigungen."
  exit 1
fi
log "${GREEN}.env Datei erfolgreich erstellt${NC}"

# Verzeichnisse erstellen
log "Erstelle benötigte Verzeichnisse"
if ! mkdir -p logs; then
  error_log "Konnte Verzeichnis 'logs' nicht erstellen. Prüfen Sie die Berechtigungen."
  exit 1
fi

if ! mkdir -p instance; then
  error_log "Konnte Verzeichnis 'instance' nicht erstellen. Prüfen Sie die Berechtigungen."
  exit 1
fi

# Docker-Image bauen und starten
log "${YELLOW}Baue und starte Backend-Container...${NC}"
log "${YELLOW}Dies kann auf einem Raspberry Pi einige Minuten dauern - bitte geduldig sein${NC}"

# Erhöhe Docker-Timeout für langsame Verbindungen und Raspberry Pi
export DOCKER_CLIENT_TIMEOUT=120
export COMPOSE_HTTP_TIMEOUT=120

# Verwende die richtige Docker Compose Version
if [ "${DOCKER_COMPOSE_V2:-false}" = true ]; then
  # Docker Compose V2 Plugin (docker compose)
  log "Baue lokales Image (ohne Pull-Versuch)..."
  if ! docker compose build --no-cache --pull=false; then
    error_log "Docker Compose Build (v2) fehlgeschlagen. Versuche mit v1 Format..."
    if ! docker-compose build --no-cache --pull=false; then
      error_log "Docker Compose Build fehlgeschlagen. Siehe Fehlermeldung oben."
      exit 1
    fi
  fi
  
  log "Starte Container aus lokalem Image..."
  if ! docker compose up -d; then
    error_log "Docker Compose Up (v2) fehlgeschlagen. Versuche mit v1 Format..."
    if ! docker-compose up -d; then
      error_log "Docker Compose Up fehlgeschlagen. Siehe Fehlermeldung oben."
      exit 1
    fi
  fi
else
  # Docker Compose V1 (docker-compose)
  log "Baue lokales Image (ohne Pull-Versuch)..."
  if ! docker-compose build --no-cache --pull=false; then
    error_log "Docker Compose Build fehlgeschlagen. Siehe Fehlermeldung oben."
    exit 1
  fi
  
  log "Starte Container aus lokalem Image..."
  if ! docker-compose up -d; then
    error_log "Docker Compose Up fehlgeschlagen. Siehe Fehlermeldung oben."
    exit 1
  fi
fi

# Prüfe, ob der Container läuft
log "Warte 10 Sekunden, bis der Container gestartet ist..."
sleep 10
if docker ps | grep -q "myp-backend"; then
  log "${GREEN}Backend-Container läuft${NC}"
else
  error_log "Backend-Container läuft nicht. Container-Status:"
  docker ps -a | grep myp-backend
  log "Container-Logs:"
  docker logs myp-backend
  exit 1
fi

# Test API-Endpunkt
log "${YELLOW}Teste Backend-API...${NC}"
log "${YELLOW}HINWEIS: Der API-Server ist bei der ersten Installation oft noch nicht erreichbar${NC}"
log "${YELLOW}Dies ist ein bekanntes Verhalten wegen der Netzwerkkonfiguration${NC}"
log "${YELLOW}Bitte nach der Installation das System neu starten, danach sollte der API-Server erreichbar sein${NC}"

# Wir versuchen es trotzdem einmal, um zu sehen, ob er vielleicht doch läuft
if curl -s http://localhost:5000/health 2>/dev/null | grep -q "healthy"; then
  log "${GREEN}Backend-API ist erreichbar und funktioniert${NC}"
else
  log "${YELLOW}Backend-API ist wie erwartet noch nicht erreichbar${NC}"
  log "${GREEN}Das ist völlig normal bei der Erstinstallation${NC}"
  log "${GREEN}Nach einem Neustart des Systems sollte der API-Server korrekt erreichbar sein${NC}"
  log "Container-Status prüfen mit: docker logs myp-backend"
fi

# Initialisierung der Datenbank prüfen
log "${YELLOW}Prüfe Datenbank-Initialisierung...${NC}"
if [ ! -s "instance/myp.db" ]; then
  log "${YELLOW}Datenbank scheint leer zu sein. Führe Initialisierungsskript aus...${NC}"
  DB_INIT_OUTPUT=$(docker exec myp-backend python -c "from app import init_db; init_db()" 2>&1)
  if [ $? -eq 0 ]; then
    log "${GREEN}Datenbank erfolgreich initialisiert${NC}"
  else
    error_log "Fehler bei der Datenbank-Initialisierung:"
    echo "$DB_INIT_OUTPUT"
    log "Container-Logs:"
    docker logs myp-backend
  fi
else
  log "${GREEN}Datenbank existiert bereits${NC}"
fi

# Teste, ob ein API-Endpunkt Daten zurückgibt
log "${YELLOW}Teste Datenbank-Verbindung über API...${NC}"
if curl -s http://localhost:5000/api/printers | grep -q "\[\]"; then
  log "${GREEN}Datenbank-Verbindung funktioniert${NC}"
else
  log "${YELLOW}API gibt keine leere Drucker-Liste zurück. Möglicherweise ist die DB nicht korrekt initialisiert.${NC}"
  log "API-Antwort:"
  curl -s http://localhost:5000/api/printers
fi

log "${GREEN}=== Installation abgeschlossen ===${NC}"
log "${YELLOW}WICHTIG: Nach der Erstinstallation ist ein Systemneustart erforderlich${NC}"
log "${YELLOW}Danach ist das Backend unter http://localhost:5000 erreichbar${NC}"
log "Anzeigen der Logs: docker logs -f myp-backend"

# Verwende die richtige Docker Compose Version für Hinweis
if [ "${DOCKER_COMPOSE_V2:-false}" = true ]; then
  log "Backend stoppen: docker compose -f $BACKEND_DIR/docker-compose.yml down"
else
  log "Backend stoppen: docker-compose -f $BACKEND_DIR/docker-compose.yml down"
fi