#!/bin/bash

# Log-Server Automatisierungs-Skript für Debian 12
# Version mit Fortschrittsanzeige

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

# Globale Variablen für Fortschritt
CURRENT_TASK=""
PROGRESS=0

# Fortschrittsanzeige Funktion
show_progress() {
    local task=$1
    local percent=$2
    local width=50
    local filled=$((percent * width / 100))
    local empty=$((width - filled))
    
    printf "\r${BLUE}### ${task}${NC}\n"
    printf "\r["
    printf "%${filled}s" | tr ' ' '='
    printf "%${empty}s" | tr ' ' ' '
    printf "] ${percent}%%"
    
    if [ $percent -eq 100 ]; then
        printf "\n"
    fi
}

# Status-Funktionen
log_success() {
    echo -e "\n${GREEN}### [✓] $1${NC}"
}

log_error() {
    echo -e "\n${RED}### [✗] $1${NC}"
}

log_info() {
    echo -e "\n${YELLOW}### [→] $1${NC}"
}

# Progress Wrapper für Befehle
run_with_progress() {
    local task=$1
    local total_steps=$2
    shift 2
    
    local step=0
    while [ $step -le $total_steps ]; do
        percent=$((step * 100 / total_steps))
        show_progress "$task" $percent
        step=$((step + 1))
        sleep 0.1
    done &
    local progress_pid=$!
    
    # Führe den eigentlichen Befehl aus
    "$@" >/dev/null 2>&1
    local result=$?
    
    # Stoppe die Fortschrittsanzeige
    kill $progress_pid 2>/dev/null
    wait $progress_pid 2>/dev/null
    
    # Zeige 100% an
    show_progress "$task" 100
    
    return $result
}

# Root-Rechte prüfen
if [[ $EUID -ne 0 ]]; then
   log_error "Dieses Skript muss mit sudo ausgeführt werden"
   exit 1
fi

clear
echo "====================================="
echo "   LOG-SERVER AUTOMATISIERUNG"
echo "   Debian 12 - Grafana/Loki/rsyslog"
echo "====================================="
echo ""

# System Update
log_info "Starte System-Update"
run_with_progress "System-Pakete werden aktualisiert" 30 \
    bash -c "apt-get update -qq && apt-get upgrade -y -qq && apt-get dist-upgrade -y -qq"

if [ $? -eq 0 ]; then
    log_success "System erfolgreich aktualisiert"
else
    log_error "System-Update fehlgeschlagen"
    exit 1
fi

# Basis-Pakete
log_info "Installiere Basis-Pakete"
run_with_progress "Basis-Pakete werden installiert" 20 \
    apt-get install -y -qq wget curl software-properties-common apt-transport-https gnupg2 unzip

log_success "Basis-Pakete installiert"

# Grafana Installation
log_info "Installiere Grafana"
show_progress "Grafana GPG-Key wird heruntergeladen" 10
wget -q -O - https://packages.grafana.com/gpg.key | apt-key add - 2>/dev/null
show_progress "Grafana GPG-Key wird heruntergeladen" 30

echo "deb https://packages.grafana.com/oss/deb stable main" | tee /etc/apt/sources.list.d/grafana.list >/dev/null
show_progress "Grafana Repository hinzugefügt" 50

apt-get update -qq
show_progress "Paketlisten aktualisiert" 70

run_with_progress "Grafana wird installiert" 30 \
    apt-get install -y -qq grafana

# Grafana konfigurieren
log_info "Konfiguriere Grafana"
sed -i 's/;http_port = 3000/http_port = 3000/' /etc/grafana/grafana.ini
systemctl daemon-reload
systemctl enable grafana-server >/dev/null 2>&1
systemctl start grafana-server

if systemctl is-active --quiet grafana-server; then
    log_success "Grafana läuft auf Port 3000"
else
    log_error "Grafana Start fehlgeschlagen - Versuche Neustart"
    systemctl restart grafana-server
    sleep 2
    if systemctl is-active --quiet grafana-server; then
        log_success "Grafana erfolgreich gestartet"
    fi
fi

# Loki Installation
log_info "Installiere Loki"
LOKI_VERSION="2.9.3"

show_progress "Loki wird heruntergeladen" 0
wget -q https://github.com/grafana/loki/releases/download/v${LOKI_VERSION}/loki-linux-amd64.zip &
wget_pid=$!

while kill -0 $wget_pid 2>/dev/null; do
    if [ -f "loki-linux-amd64.zip" ]; then
        size=$(stat -c%s "loki-linux-amd64.zip" 2>/dev/null || echo 0)
        # Geschätzte Größe: ~50MB
        percent=$((size * 100 / 52428800))
        [ $percent -gt 100 ] && percent=100
        show_progress "Loki wird heruntergeladen" $percent
    fi
    sleep 0.5
done
wait $wget_pid
show_progress "Loki wird heruntergeladen" 100

log_info "Entpacke und installiere Loki"
unzip -q loki-linux-amd64.zip
mv loki-linux-amd64 /usr/local/bin/loki
chmod +x /usr/local/bin/loki
rm loki-linux-amd64.zip

# Loki Konfiguration
mkdir -p /etc/loki /var/lib/loki
cat > /etc/loki/loki-config.yaml << 'EOF'
auth_enabled: false

server:
  http_listen_port: 3100
  grpc_listen_port: 9096

common:
  path_prefix: /var/lib/loki
  storage:
    filesystem:
      chunks_directory: /var/lib/loki/chunks
      rules_directory: /var/lib/loki/rules
  replication_factor: 1
  ring:
    instance_addr: 127.0.0.1
    kvstore:
      store: inmemory

schema_config:
  configs:
    - from: 2020-10-24
      store: boltdb-shipper
      object_store: filesystem
      schema: v11
      index:
        prefix: index_
        period: 24h

ruler:
  alertmanager_url: http://localhost:9093

analytics:
  reporting_enabled: false
EOF

# Loki Systemd Service
cat > /etc/systemd/system/loki.service << 'EOF'
[Unit]
Description=Loki service
After=network.target

[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/loki -config.file /etc/loki/loki-config.yaml
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable loki >/dev/null 2>&1
systemctl start loki
sleep 3

if systemctl is-active --quiet loki; then
    log_success "Loki läuft auf Port 3100"
else
    log_error "Loki Start fehlgeschlagen - Versuche Neustart"
    systemctl restart loki
    sleep 3
    if systemctl is-active --quiet loki; then
        log_success "Loki erfolgreich gestartet"
    fi
fi

# Promtail Installation
log_info "Installiere Promtail"
PROMTAIL_VERSION="2.9.3"

show_progress "Promtail wird heruntergeladen" 0
wget -q https://github.com/grafana/loki/releases/download/v${PROMTAIL_VERSION}/promtail-linux-amd64.zip &
wget_pid=$!

while kill -0 $wget_pid 2>/dev/null; do
    if [ -f "promtail-linux-amd64.zip" ]; then
        size=$(stat -c%s "promtail-linux-amd64.zip" 2>/dev/null || echo 0)
        # Geschätzte Größe: ~50MB
        percent=$((size * 100 / 52428800))
        [ $percent -gt 100 ] && percent=100
        show_progress "Promtail wird heruntergeladen" $percent
    fi
    sleep 0.5
done
wait $wget_pid
show_progress "Promtail wird heruntergeladen" 100

log_info "Entpacke und installiere Promtail"
unzip -q promtail-linux-amd64.zip
mv promtail-linux-amd64 /usr/local/bin/promtail
chmod +x /usr/local/bin/promtail
rm promtail-linux-amd64.zip

# Promtail Konfiguration (WICHTIG: Korrigiert aus dem ersten Skript)
mkdir -p /etc/promtail /var/lib/promtail
cat > /etc/promtail/promtail-config.yaml << 'EOF'
server:
  http_listen_port: 9080
  grpc_listen_port: 0

positions:
  filename: /var/lib/promtail/positions.yaml

clients:
  - url: http://localhost:3100/loki/api/v1/push

scrape_configs:
  # Remote System Logs (ALLE Netzwerk-Logs nach IP sortiert)
  - job_name: remote
    static_configs:
      - targets:
          - localhost
        labels:
          job: remote
          type: network_logs
          __path__: /var/log/remote/**/*.log
    pipeline_stages:
      - regex:
          expression: '/var/log/remote/(?P<source_ip>[^/]+)/'
      - labels:
          source_ip:
  
  # Log-Server eigene Logs (nur dieser Server)
  - job_name: lokal
    static_configs:
      - targets:
          - localhost
        labels:
          job: lokal
          type: local_system
          hostname: loggserver
          __path__: /var/log/syslog
EOF

# Promtail Systemd Service
cat > /etc/systemd/system/promtail.service << 'EOF'
[Unit]
Description=Promtail service
After=network.target loki.service

[Service]
Type=simple
User=root
ExecStart=/usr/local/bin/promtail -config.file /etc/promtail/promtail-config.yaml
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable promtail >/dev/null 2>&1
systemctl start promtail
sleep 3

if systemctl is-active --quiet promtail; then
    log_success "Promtail läuft auf Port 9080"
else
    log_error "Promtail Start fehlgeschlagen - Versuche Neustart"
    systemctl restart promtail
    sleep 3
    if systemctl is-active --quiet promtail; then
        log_success "Promtail erfolgreich gestartet"
    fi
fi

# rsyslog Installation
log_info "Installiere rsyslog"
run_with_progress "rsyslog wird installiert" 20 \
    apt-get install -y -qq rsyslog

# rsyslog Konfiguration
log_info "Konfiguriere rsyslog für Remote-Logging"
cat > /etc/rsyslog.d/10-remote.conf << 'EOF'
# Remote Logging aktivieren
module(load="imudp")
input(type="imudp" port="514")

module(load="imtcp")
input(type="imtcp" port="514")

# Template für Remote-Logs - Sortiert nach IP-Adresse
$template RemoteLogsByIP,"/var/log/remote/%FROMHOST-IP%/system.log"

# Alle Remote-Logs nach IP sortieren (alles außer localhost)
if $fromhost-ip != '127.0.0.1' then ?RemoteLogsByIP
& stop
EOF

# Log-Verzeichnisse
mkdir -p /var/log/remote
chmod 755 /var/log/remote

systemctl restart rsyslog
if systemctl is-active --quiet rsyslog; then
    log_success "rsyslog läuft auf Port 514 (UDP/TCP)"
else
    log_error "rsyslog Start fehlgeschlagen"
fi

# Log-Rotation
log_info "Konfiguriere Log-Rotation und Archivierung"
cat > /etc/logrotate.d/remote-logs << 'EOF'
# Remote Logs (nach IP sortiert)
/var/log/remote/*/*.log {
    daily
    rotate 1
    compress
    delaycompress
    missingok
    notifempty
    create 644 root root
    postrotate
        # Archiv-Verzeichnis pro IP erstellen
        for dir in /var/log/remote/*/; do
            if [ -d "$dir" ]; then
                ip_addr=$(basename "$dir")
                mkdir -p "/var/log/remote/$ip_addr/archiv"
                mv /var/log/remote/$ip_addr/*.gz /var/log/remote/$ip_addr/archiv/ 2>/dev/null || true
            fi
        done
        /usr/bin/systemctl reload rsyslog > /dev/null 2>&1 || true
    endscript
}
EOF

log_success "Log-Rotation eingerichtet"

# Cleanup-Skript
cat > /usr/local/bin/cleanup-old-logs.sh << 'EOF'
#!/bin/bash
find /var/log/remote/*/archiv -type f -mtime +30 -delete 2>/dev/null
EOF
chmod +x /usr/local/bin/cleanup-old-logs.sh
(crontab -l 2>/dev/null; echo "0 2 * * * /usr/local/bin/cleanup-old-logs.sh") | crontab -
log_success "Automatisches Cleanup konfiguriert"

# Firewall
if command -v ufw &> /dev/null; then
    log_info "Konfiguriere Firewall-Regeln"
    ufw allow 514/udp comment 'rsyslog UDP' >/dev/null 2>&1
    ufw allow 514/tcp comment 'rsyslog TCP' >/dev/null 2>&1
    ufw allow 3000/tcp comment 'Grafana' >/dev/null 2>&1
    ufw allow 3100/tcp comment 'Loki' >/dev/null 2>&1
    ufw allow 9080/tcp comment 'Promtail' >/dev/null 2>&1
    log_success "Firewall-Regeln hinzugefügt"
fi

# Grafana Datenquelle
log_info "Konfiguriere Grafana Datenquellen"
mkdir -p /etc/grafana/provisioning/datasources
cat > /etc/grafana/provisioning/datasources/loki.yaml << 'EOF'
apiVersion: 1

datasources:
  - name: Loki
    type: loki
    access: proxy
    url: http://localhost:3100
    isDefault: true
    editable: true
EOF

# Dashboard
mkdir -p /etc/grafana/provisioning/dashboards
cat > /etc/grafana/provisioning/dashboards/dashboard.yaml << 'EOF'
apiVersion: 1

providers:
  - name: 'default'
    orgId: 1
    folder: ''
    type: file
    disableDeletion: false
    updateIntervalSeconds: 10
    options:
      path: /etc/grafana/provisioning/dashboards
EOF

cat > /etc/grafana/provisioning/dashboards/logs-dashboard.json << 'EOF'
{
  "dashboard": {
    "title": "System Logs Dashboard",
    "panels": [
      {
        "datasource": "Loki",
        "gridPos": {"h": 10, "w": 24, "x": 0, "y": 0},
        "id": 1,
        "targets": [
          {
            "expr": "{job=\"lokal\"}",
            "refId": "A"
          }
        ],
        "title": "Lokale Logs (Log-Server)",
        "type": "logs"
      },
      {
        "datasource": "Loki",
        "gridPos": {"h": 10, "w": 24, "x": 0, "y": 10},
        "id": 2,
        "targets": [
          {
            "expr": "{job=\"remote\"}",
            "refId": "B"
          }
        ],
        "title": "Remote Logs (Alle Netzwerk-Geräte)",
        "type": "logs"
      }
    ],
    "schemaVersion": 27,
    "version": 1
  },
  "overwrite": true
}
EOF

systemctl restart grafana-server
log_success "Grafana Dashboard erstellt"

# Finale Überprüfung
echo ""
log_info "Überprüfe alle Services"
echo ""
echo "====================================="
echo "SERVICE STATUS:"
echo "====================================="

services=("grafana-server" "loki" "promtail" "rsyslog")
all_running=true

for service in "${services[@]}"; do
    if systemctl is-active --quiet $service; then
        echo -e "${GREEN}### [✓] $service läuft${NC}"
    else
        echo -e "${RED}### [✗] $service läuft nicht${NC}"
        all_running=false
    fi
done

echo ""
echo "====================================="
echo "ZUGRIFFS-INFORMATIONEN:"
echo "====================================="
IP=$(hostname -I | awk '{print $1}')
echo -e "${GREEN}Grafana Web-Interface:${NC} http://$IP:3000"
echo -e "${GREEN}Standard Login:${NC} admin / admin"
echo -e "${GREEN}Loki API:${NC} http://$IP:3100"
echo -e "${GREEN}Promtail Metrics:${NC} http://$IP:9080"
echo -e "${GREEN}Syslog Port:${NC} 514 (UDP/TCP)"
echo ""
echo -e "${GREEN}Log-Verzeichnisse:${NC}"
echo "  - Lokale Logs: /var/log/syslog"
echo "  - Remote Logs: /var/log/remote/[IP-ADRESSE]/system.log"
echo "  - Archive: /var/log/remote/[IP-ADRESSE]/archiv/"
echo ""
echo -e "${YELLOW}Beispiel-Struktur:${NC}"
echo "  /var/log/remote/192.168.179.5/system.log"
echo "  /var/log/remote/10.0.0.1/system.log"
echo "  /var/log/remote/192.168.179.10/system.log (UniFi)"
echo ""

if $all_running; then
    echo -e "${GREEN}###################################${NC}"
    echo -e "${GREEN}### INSTALLATION ERFOLGREICH! ###${NC}"
    echo -e "${GREEN}###################################${NC}"
else
    echo -e "${RED}#######################################${NC}"
    echo -e "${RED}### WARNUNG: Einige Services offline ###${NC}"
    echo -e "${RED}#######################################${NC}"
    echo ""
    echo "Debug mit: journalctl -u {servicename} -n 50"
fi

echo "====================================="