#!/bin/bash

# ----------------------------------------------------------------------------------
# updates LeTTo 1.2 to 1.3
# ----------------------------------------------------------------------------------

# --------------------------------------------------------------------------------
# parameter
# --------------------------------------------------------------------------------
# Alle übergebenen Parameter prüfen
isagent=
for parameter in "$@"; do
    case "$parameter" in
        -a|--agent)
            isagent=true
            ;;
    esac
done

# Base directory for Server-Installation
lettobase=/opt/letto

# Ziel-Tag für alle Docker-Images
lettotag=stable-1.3

# Bei nicht vorhandenen Dateimustern Schleifen einfach ueberspringen
shopt -s nullglob

# --------------------------------------------------------------------------------
# Check if LeTTo 1.2 is installed
# --------------------------------------------------------------------------------
composesetup="$lettobase/docker/compose/setup"
composeletto="$lettobase/docker/compose/letto"
composemysql="$lettobase/docker/compose/mysql"

if [ ! -d "$composesetup" ]; then
  echo "LeTTo 1.2 setup is not installed in $composesetup - stopping update to 1.3"
  exit 1
fi

# ask user for confirmation
#read -p "Are you sure you want to update LeTTo 1.2 to 1.3? (y/n) " confirm
#if [[ ! "$confirm" =~ ^[yY]$ ]]; then
#  echo "Update cancelled."
#  exit 1
#fi

# ------------------------------------------------------------------------------------------
# Backup-Verzeichnis anlegen
# ------------------------------------------------------------------------------------------
set -e
composebackup="$lettobase/docker/compose/backup"
rm -rf $composebackup
mkdir -p $composebackup/setup
mkdir -p $composebackup/letto
mkdir -p $composebackup/mysql

cp -a "$composesetup/." "$composebackup/setup/"
cp -a "$composeletto/." "$composebackup/letto/"
cp -a "$composemysql/." "$composebackup/mysql/"

# --------------------------------------------------------------------------------
# env-Datei anpassen
# --------------------------------------------------------------------------------
setupenv="$composesetup/.env"
lettoenv="$composeletto/.env"
tmpfile="${lettoenv}.tmp"

# Sicherheitskopien wie im Windows-Script
cp -f "$setupenv" "$composeletto/setup.env.bak"
cp -f "$lettoenv" "$composeletto/letto.env.bak"

while IFS= read -r line || [[ -n "$line" ]]; do
    # Leerzeilen und Kommentare ignorieren
    [[ -z "$line" ]] && continue
    [[ "$line" =~ ^[[:space:]]*# ]] && continue

    # Nur Einträge NAME=WERT berücksichtigen
    [[ "$line" != *"="* ]] && continue

    key="${line%%=*}"

    # Führende/trailing Leerzeichen beim Key entfernen
    key="${key#"${key%%[![:space:]]*}"}"
    key="${key%"${key##*[![:space:]]}"}"

    # Variable nur ergänzen, wenn sie in lettoenv nicht existiert
    if ! grep -q -E "^[[:space:]]*${key}=" "$lettoenv"; then
        printf '%s\n' "$line"
    fi
done < "$setupenv" > "$tmpfile"

cat "$lettoenv" >> "$tmpfile"
mv "$tmpfile" "$lettoenv"

sed -i 's/^REDIRECT=.*/REDIRECT=app/' "$lettoenv"

#------------------------------------------------------------------------------------------
# Download alles notwendigen Dateien fuer 1.3
#------------------------------------------------------------------------------------------
download="$lettobase/docker/compose/downloadtmp"
baseurl="https://build.letto.at/download/install-1.3"
mkdir -p "$download"

download_file() {
    local source="$1"
    local target="$download/${source##*/}"

    echo "Download: ${source##*/}"

    wget --no-check-certificate --auth-no-challenge \
        "$baseurl/$source" \
        -O "$target"
}

download_file "scripts/debian-ubuntu/settag.sh"
download_file "scripts/debian-ubuntu/replacetag.sh"
download_file "scripts/debian-ubuntu/replaceschool.sh"
download_file "scripts/debian-ubuntu/startall.sh"
download_file "scripts/debian-ubuntu/stopall.sh"

download_file "yml/docker-lettoserver-school.yml"
download_file "yml/docker-data-school.yml"
download_file "yml/docker-compose-mysql.yml"
download_file "yml/docker-compose-setup.yml"
download_file "yml/docker-compose-mongo.yml"
download_file "yml/docker-compose-redis.yml"
download_file "yml/docker-compose-proxy.yml"
download_file "yml/docker-service-login.yml"
download_file "yml/docker-questionextern.yml"

download_file "yml/docker-service-app.yml"
download_file "yml/docker-service-download.yml"
download_file "yml/docker-service-edit.yml"
download_file "yml/docker-service-export.yml"
download_file "yml/docker-service-htmlpreview.yml"
download_file "yml/docker-service-image.yml"
download_file "yml/docker-service-lehrplan.yml"
download_file "yml/docker-service-lti.yml"
download_file "yml/docker-service-main.yml"
download_file "yml/docker-service-plugin.yml"
download_file "yml/docker-service-pluginmath.yml"
download_file "yml/docker-service-pluginsourcecode.yml"
download_file "yml/docker-service-plugintester.yml"
download_file "yml/docker-service-pluginuhr.yml"
download_file "yml/docker-service-question.yml"

# ------------------------------------------------------------------------------------------
# yml anpassen
# ------------------------------------------------------------------------------------------
# Setup erst zum Schluss beenden und neu konfigurieren
#cd "$composesetup"
#docker compose down

cd "$composemysql"
docker compose down

mkdir -p /opt/letto/docker/storage/database-dump
echo "Erstelle Backup der MySQL-Datenbanken in /opt/letto/docker/storage/database-dump/lettomysql-backup.tar.gz"
cd /opt/letto/docker/storage/database-dump
docker run --rm -v lettomysql:/source:ro -v /opt/letto/docker/storage/database-dump:/backup alpine tar czf /backup/lettomysql-backup.tar.gz -C /source .
sha256sum /opt/letto/docker/storage/database-dump/lettomysql-backup.tar.gz >/opt/letto/docker/storage/database-dump/lettomysql-backup.tar.gz.sha256

cd "$composeletto"

# Login und Proxy erst zum Schluss beenden und neu konfigurieren
# docker compose -f "$composeletto/docker-compose.yml" down
echo "Erstelle Backup der MongoDB-Datenbanken in /opt/letto/docker/storage/database-dump/mongo.tgz"
docker exec -t letto-mongo /dump.sh
echo "Erstelle Backup der Redis-Datenbanken in /opt/letto/docker/storage/database-dump/redis.tgz"
docker exec -t letto-redis /dump.sh
echo "Stoppen von MongoDB und Redis"
docker compose -f "$composeletto/docker-service-mongo.yml" down
docker compose -f "$composeletto/docker-service-redis.yml" down

# Hilfsscripts fuer Ubuntu laden
cp -f "$download/settag.sh"        "$composeletto/settag.sh"
cp -f "$download/replacetag.sh"    "$composeletto/replacetag.sh"
cp -f "$download/replaceschool.sh" "$composeletto/replaceschool.sh"
cp -f "$download/startall.sh"      "$composeletto/startall.sh"
cp -f "$download/stopall.sh"       "$composeletto/stopall.sh"
chmod 755 "$composeletto"/*.sh

# ------------------------------------------------------------------------------------------
# Schulen
# ------------------------------------------------------------------------------------------
for file in "$composeletto"/docker-compose-*.yml; do
    filename="$(basename "$file" .yml)"

    # "docker-compose-" vom Dateinamen entfernen
    name="${filename#docker-compose-}"

    echo "Datei: $(basename "$file")"
    echo "school: $name"

    # Nummer aus LETTO_<Nummer>_ in der Quelldatei ermitteln
    lettonr="$(grep -oE 'LETTO_[0-9]+_' "$file" | head -n 1 | sed -E 's/LETTO_([0-9]+)_/\1/')"

    if [ -z "$lettonr" ]; then
        echo "FEHLER: Keine LETTO-Nummer in $(basename "$file") gefunden! Datei wird mal ignoriert und nicht aktualisiert oder gestartet."
    else

      echo "LETTO-Nummer: $lettonr"

      docker compose -f "$file" down

      cp -f "$download/docker-lettoserver-school.yml" "$composeletto/docker-lettoserver-$name.yml"
      cp -f "$download/docker-data-school.yml" "$composeletto/docker-data-$name.yml"

      # In den heruntergeladenen Dateien LETTO_<beliebige Nummer>_ ersetzen
      sed -E -i "s/LETTO_[0-9]+/LETTO_${lettonr}/g" \
          "$composeletto/docker-data-$name.yml"
      sed -E -i "s/LETTO_[0-9]+/LETTO_${lettonr}/g" \
          "$composeletto/docker-lettoserver-$name.yml"
      sed -E -i "s/# School [0-9]+/# School ${lettonr}/g" \
          "$composeletto/docker-data-$name.yml"
      sed -E -i "s/# School [0-9]+/# School ${lettonr}/g" \
          "$composeletto/docker-lettoserver-$name.yml"
      sed -E -i "s/data[0-9]+:/data${lettonr}:/g" \
          "$composeletto/docker-data-$name.yml"
      sed -E -i "s/letto[0-9]+:/letto${lettonr}:/g" \
          "$composeletto/docker-lettoserver-$name.yml"

      # Ports anhand der LETTO-Nummer anpassen
      newport=$((4100 + lettonr))
      sed -i "s/:-4100/:-${newport}/g" \
          "$composeletto/docker-lettoserver-$name.yml"

      newport=$((4200 + lettonr))
      sed -i "s/:-4200/:-${newport}/g" \
          "$composeletto/docker-data-$name.yml"

      "$composeletto/settag.sh" "$composeletto/docker-data-$name.yml" "$lettotag"
      "$composeletto/settag.sh" "$composeletto/docker-lettoserver-$name.yml" "$lettotag"

      docker compose -f "$composeletto/docker-lettoserver-$name.yml" up -d --pull always
      docker compose -f "$composeletto/docker-data-$name.yml" up -d --pull always

      # Alte Schul-Compose-Datei entfernen
      rm -f "$file"

      echo
    fi
 done

# ------------------------------------------------------------------------------------------
# setup, mysql, mongo, redis, login, proxy - mysql und mongo bleiben unverändert
# ------------------------------------------------------------------------------------------
cp -f "$composemysql/docker-compose.yml"       "$composeletto/docker-compose-mysql.yml"
cp -f "$composeletto/docker-service-mongo.yml" "$composeletto/docker-compose-mongo.yml"
# cp -f "$download/docker-compose-mysql.yml" "$composeletto/docker-compose-mysql.yml"
# cp -f "$download/docker-compose-mongo.yml" "$composeletto/docker-compose-mongo.yml"
cp -f "$download/docker-compose-redis.yml" "$composeletto/docker-compose-redis.yml"

cp -f "$download/docker-compose-setup.yml" "$composeletto/docker-compose-setup.yml"
cp -f "$download/docker-compose-proxy.yml" "$composeletto/docker-compose-proxy.yml"
cp -f "$download/docker-service-login.yml" "$composeletto/docker-service-login.yml"

# "$composeletto/settag.sh" "$composeletto/docker-compose-mysql.yml" "$lettotag"
# "$composeletto/settag.sh" "$composeletto/docker-compose-mongo.yml" "$lettotag"
"$composeletto/settag.sh" "$composeletto/docker-compose-setup.yml" "$lettotag"
"$composeletto/settag.sh" "$composeletto/docker-compose-redis.yml" "$lettotag"
"$composeletto/settag.sh" "$composeletto/docker-compose-proxy.yml" "$lettotag"
"$composeletto/settag.sh" "$composeletto/docker-service-login.yml" "$lettotag"

# Stoppe Login und Proxy, da diese in der neuen Version 1.3 neu gestartet werden
echo Restarte Login und Proxy
sleep 1
docker compose -f "$composeletto/docker-compose.yml" down
echo "Warte 3 Sekunden …"
sleep 3

echo starte mysql, mongo, redis, proxy und login
docker compose -f "$composeletto/docker-compose-proxy.yml" up -d --pull always
docker compose -f "$composeletto/docker-service-login.yml" up -d --pull always
docker compose -f "$composeletto/docker-compose-mysql.yml" up -d --pull always
docker compose -f "$composeletto/docker-compose-mongo.yml" up -d --pull always
docker compose -f "$composeletto/docker-compose-redis.yml" up -d --pull always
echo "Warte 30 Sekunden …"
sleep 30

# Alte Dateien entfernen
rm -f "$composeletto/docker-compose.yml"
rm -f "$composeletto/docker-service-redis.yml"
rm -f "$composeletto/docker-service-mongo.yml"

# ------------------------------------------------------------------------------------------
# Services
# ------------------------------------------------------------------------------------------
questionnr=1

echo "Update und Start services …"
for file in "$composeletto"/docker-service-*.yml; do
    filename="$(basename "$file" .yml)"

    # "docker-service-" vom Dateinamen entfernen
    name="${filename#docker-service-}"

    echo "Datei: $(basename "$file")"
    echo "Name: $name"

    docker compose -f "$file" down

    # Pruefen, ob der Name mit "question-" beginnt
    if [[ "$name" == question-* ]]; then
        echo "Question-Service"
        restname="${name:9}"
        echo "Restlicher Name: $restname"

        # Nummer aus QUESTION<Nummer>_ bzw. QUESTION_<Nummer>_ ermitteln.
        # Beide Schreibweisen werden akzeptiert, da die Windows-Datei hier
        # unterschiedliche Muster beim Lesen und Schreiben verwendet.
        found_questionnr="$(grep -oE 'QUESTION_?[0-9]+_' "$file" | head -n 1 | sed -E 's/QUESTION_?([0-9]+)_/\1/')"
        if [ -n "$found_questionnr" ]; then
            questionnr="$found_questionnr"
        else
            echo "FEHLER: Keine QUESTION-Nummer in $(basename "$file") gefunden!"
            exit 1
        fi

        echo "QUESTION-Nummer: $questionnr"

        questionfile="$composeletto/docker-questionextern-$restname.yml"

        cp -f "$download/docker-questionextern.yml" "$questionfile"

        "$composeletto/settag.sh" "$questionfile" "$lettotag"

        # QUESTION<Nummer>_ bzw. QUESTION_<Nummer>_ ersetzen
        sed -E -i "s/QUESTION_[0-9]+_/QUESTION_${questionnr}_/g" "$questionfile"
        sed -E -i "s/question[0-9]+:/question${questionnr}:/g" "$questionfile"
        sed -E -i "s/# Question [0-9]+/# Question ${questionnr}/g" "$questionfile"

        # Port fuer den externen Question-Service setzen
        newport=$((4300 + questionnr))
        sed -i "s/:-15102/:-${newport}/g" "$questionfile"

        docker compose -f "$questionfile" up -d --pull always

        # Alte Service-Datei entfernen
        rm -f "$file"

        questionnr=$((questionnr + 1))
    else
        echo "Normaler Service"

        if [[ -s "$download/docker-service-$name.yml" ]]; then
          cp -f "$download/docker-service-$name.yml" "$composeletto/docker-service-$name.yml"

          "$composeletto/settag.sh" "$composeletto/docker-service-$name.yml" "$lettotag"
        fi
        docker compose -f "$composeletto/docker-service-$name.yml" up -d --pull always
    fi

    echo
 done

# jetzt Setup beenden
echo "Warte 30 Sekunden …"
sleep 30

echo "Erzeugt Restartscript in $lettobase/docker/restartsetup.sh"
cat > "$lettobase/docker/restartsetup.sh" <<EOF
#!/bin/bash

cd "$composesetup"
docker compose down --timeout 30

while docker container inspect letto-setup >/dev/null 2>&1; do
    echo "Warte auf alten setup-Container ..."
    sleep 1
done

cd "$composeletto"

rm -rf "$composesetup"
rm -rf "$composemysql"

echo "starte setup"
docker compose -f "$composeletto/docker-compose-setup.yml" up -d --pull always
echo Scriptfile löschen
rm -f -- "$lettobase/docker/restartsetup.sh"
EOF

chmod +x "$lettobase/docker/restartsetup.sh"
echo "Restarte Setup - BITTE 1 MINUTE WARTEN und dann SEITE NEU LADEN und wieder ANMELDEN"

if [[ "$isagent" == true ]]; then
    docker run -d --rm --pull=always -v /var/run/docker.sock:/var/run/docker.sock -v /opt/letto:/opt/letto lettohub/dockeragent:stable /opt/letto/docker/restartsetup.sh
else
    /opt/letto/docker/restartsetup.sh
fi

# ------------------------------------------------------------------------------------------
# FINISH
# ------------------------------------------------------------------------------------------
echo
echo "Update auf Version-1.3 fertig! Bitte Setup-Seite in einer Minute neu laden und wieder anmelden."

