#!/bin/bash
##################################################################################
### Das Skript klont die angegeben Datenbanken des SVWS-Docker-Container N-mal ###
##################################################################################
#  
# Copyright (c) (Mai 2026) Theo Richter & David Klein
# 
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# 
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# 
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
##################################################################################


# Standardwerte initialisieren
FOLDER=""
PASSWORD=""
FQDN=""
SVWSPORTNUMBER="8443"
SVWSVERSION=""
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
TESTDB_SQLITE="https://github.com/SVWS-NRW/SVWS-TestMDBs/raw/refs/heads/main/GOST_Abitur/Abi-Test-Daten-04/Gym_22_23_1.sqlite"



usage() {
    echo "Benutzung: $0 -o <FOLDER> -v <SVWSVERSION> [-p <PASSWORD>] [-dn <FQDN>] [-pt <PORTNUMBER>]"
    echo "  -o  Ordnerpfad (Pflichtangabe)"
    echo "  -v  SVWS Server Version (Pflichtangabe)"
    echo "  -sv  Schild3 Version (Pflichtangabe)"
    echo "  -p  Passwort (optional, sonst Autogenerierung)"
    echo "  -dn Fully Qualified Domain Name (Fallback: Ordnername)"
    echo "  -pt Portnummer (Standard: 8443)"
    exit 1
}

# Parameter verarbeiten
while [[ $# -gt 0 ]]; do
    case $1 in
        -o) FOLDER="$2"; shift 2 ;;
        -v) SVWSVERSION="$2"; shift 2 ;;
        -sv) SCHILDVERSION="$2"; shift 2 ;;
        -p) PASSWORD="$2"; shift 2 ;;
        -dn) FQDN="$2"; shift 2 ;;
        -pt) SVWSPORTNUMBER="$2"; shift 2 ;;
        *) usage ;;
    esac
done



# 1. Pflichtangaben prüfen
if [[ -z "$FOLDER" ]] || [[ -z "$SVWSVERSION" ]] || [[ -z "$SCHILDVERSION" ]]; then
    echo "Fehler: Die Parameter -o (FOLDER) und -v (SVWSVERSION) und  -sv (SCHILDVERSION) sind zwingend erforderlich."
    usage
fi


# Installation von Docker

## locales auf de setzen
apt update
apt install -y locales
sed -i '/^# de_DE.UTF-8 UTF-8/s/^# //' /etc/locale.gen
locale-gen
update-locale LANG=de_DE.UTF-8
export LANG=de_DE.UTF-8
export LC_ALL=de_DE.UTF-8

## updaten
apt upgrade -y
apt autoremove -y

## Add Docker's official GPG key:
apt install -y ca-certificates curl nmap 
install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc
chmod a+r /etc/apt/keyrings/docker.asc

## Add the repository to Apt sources:
tee /etc/apt/sources.list.d/docker.sources <<EOF
Types: deb
URIs: https://download.docker.com/linux/debian
Suites: $(. /etc/os-release && echo "$VERSION_CODENAME")
Components: stable
Signed-By: /etc/apt/keyrings/docker.asc
EOF



apt update
apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin nmap net-tools curl zip

curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
apt install -y nodejs
node -v
npm -v


# 2. Port-Check
if command -v lsof >/dev/null 2>&1; then
    if lsof -Pi :"$PORTNUMBER" -sTCP:LISTEN -t >/dev/null ; then
        echo "FEHLER: Port $PORTNUMBER wird bereits verwendet!"
        exit 1
    fi
fi

# 3. Fallbacks
[[ -z "$FQDN" ]] && FQDN="$FOLDER"

if [[ -z "$PASSWORD" ]]; then
    PASSWORD=$(openssl rand -base64 12)
    IS_AUTOGENERATED=true
fi

# 4. Verzeichnisstruktur vorbereiten
mkdir -p "$FOLDER/volume/mariadb"
mkdir -p "$FOLDER/volume/mariadb/conf.d"
mkdir -p "$FOLDER/volume/svws"
mkdir -p "$FOLDER/volume/nginx"
mkdir -p "$FOLDER/volume/samba"
mkdir -p "$FOLDER/volume/samba/storage"
mkdir -p "$FOLDER/volume/samba/storage/schild3"
mkdir -p "$FOLDER/volume/samba/storage/schild3_Arbeitsverzeichnis"
mkdir -p "$FOLDER/volume/samba/storage/schulungsunterlagen"
mkdir -p "$FOLDER/volume/samba/storage/schild2"
# Berechtigungen sicherstellen, damit MariaDB schreiben darf
chmod -R 777 "$FOLDER/volume"


# Schild 3 runterladen und entpacken: 
cd "$FOLDER/volume/samba/storage/schild3/"
wget -N https://github.com/SVWS-NRW/Schild-NRW-3/releases/download/v${SCHILDVERSION}/Setup_SchILD3_v${SCHILDVERSION}.zip
unzip -o *.zip
cd "$SCRIPT_DIR"

# Mariadb config überschreiben, sodass Schild zugang bekommt
cat <<EOF > "$FOLDER/volume/mariadb/conf.d/custom.cnf"
[mysqld]
bind-address = 0.0.0.0
EOF


# 5. .env Datei erzeugen
cat <<EOF > "$FOLDER/.env"
IMPORT_TEST_DATA=false
MARIADB_ROOT_PASSWORD=$PASSWORD
MYSQL_ROOT_PASSWORD=$PASSWORD
MARIADB_HOST=mariadb
SVWS_TLS_KEYSTORE_PASSWORD=$PASSWORD
SVWS_TLS_KEY_ALIAS=svws
SVWS_TLS_KEYSTORE_PATH=.
SVWS_TLS_CERT_CN=SVWSTESTSERVER
SVWS_TLS_CERT_OU=SVWSOU
SVWS_TLS_CERT_O=SVWSO
SVWS_TLS_CERT_L=D
SVWS_TLS_CERT_S=NRW
SVWS_TLS_CERT_C=DE
SERVERNAME=$FQDN
PORT=$SVWSPORTNUMBER
EOF

# 6. docker-compose.yml erzeugen
cat <<EOF > "$FOLDER/docker-compose.yml"
services:
  samba:
    image: dockurr/samba
    container_name: ${FQDN}_samba
    environment:
      NAME: "${FQDN}"
      USER: "${FQDN}"
      PASS: "${PASSWORD}"
    ports:
      - 445:445
    volumes:
      - ./volume/samba/storage:/storage
    restart: always

  mariadb:
    restart: always
    image: mariadb:latest
    container_name: ${FQDN}_mariadb
    env_file:
      - .env
    healthcheck:
      test: ["CMD-SHELL", "mariadb-admin ping -h localhost -u root -p${PASSWORD}"]
      start_period: 20s
      interval: 5s
      timeout: 5s
      retries: 3
    volumes:
      - ./volume/mariadb:/var/lib/mysql
      - ./volume/mariadb/conf.d:/etc/mysql/conf.d
    ports:
      - "3306:3306"

  svws-server:
    image: svwsnrw/svws-server:$SVWSVERSION
    depends_on:
      mariadb:
        condition: service_healthy
    container_name: $FQDN
    ports:
      - "$SVWSPORTNUMBER:8443"
    volumes:
      - ./volume/svws:/opt/app/svws/conf
    env_file:
      - .env
EOF


cd "$FOLDER" && docker compose up -d



## WeNom unter apache auf Port 443

DOMAIN=""
PHPVERSION=8.4
INSTALLPATH=/var/www/html/wenom

# Parameter-Abfrage mit getopts
while getopts "v:d:" opt; do
  case $opt in
    v) SVWSVERSION=$OPTARG ;;
    d) DOMAIN=$OPTARG ;;
    *) echo "Benutzung: $0 -v [SVWS-Version] -d [Domainname]" >&2
       exit 1 ;;
  esac
done

# Verpflichtende Prüfung der SVWS-Version
if [ -z "$SVWSVERSION" ]; then
    echo -e "\e[31mFehler: Die SVWS-Version (-v) muss angegeben werden!\e[0m"
    echo "Beispiel: $0 -v 1.2.2"
    exit 1
fi

# Domain optional - Fallback auf Server-IP
if [ -z "$DOMAIN" ]; then
    # Ermittelt die primäre öffentliche/lokale IP-Adresse
    DOMAIN=$(hostname -I | awk '{print $1}')
    echo "Keine Domain angegeben. Nutze IP-Adresse: $DOMAIN"
    USEIP=true
fi


echo "Starte Installation von WeNoM $SVWSVERSION auf $DOMAIN..."

### Apache2 und PHP installation
apt update && apt upgrade -y 
apt install -y curl zip unzip dnsutils nmap net-tools nano mc ca-certificates gnupg2 lsb-release openssl apt-transport-https gnupg
apt install -y apache2 php${PHPVERSION} php${PHPVERSION}-fpm php${PHPVERSION}-sqlite3

a2enmod proxy_fcgi setenvif rewrite headers ssl
a2enconf php${PHPVERSION}-fpm

# PHP Config anpassen
sed -i "s|;extension=pdo_sqlite.*$|extension=pdo_sqlite|" /etc/php/${PHPVERSION}/fpm/php.ini

# Verzeichnis-Berechtigungen in Apache setzen
if ! grep -q "<Directory ${INSTALLPATH}>" /etc/apache2/apache2.conf; then
echo "
<Directory ${INSTALLPATH}>
   Options Indexes FollowSymLinks Includes ExecCGI
   AllowOverride All
   Require all granted
</Directory>" >> /etc/apache2/apache2.conf
fi

### Apache Port 80  zu gunsten des Nginx ausschalten:
# löschen der 000-default.conf 
rm /etc/apache2/sites-available/000-default.conf

### SSL VHost konfigurieren
a2ensite default-ssl.conf
mkdir -p ${INSTALLPATH}/public

# DocumentRoot und ServerName in der SSL-Config setzen
sed -i "s|DocumentRoot.*$|DocumentRoot ${INSTALLPATH}/public|" /etc/apache2/sites-available/default-ssl.conf
if ! grep -q "ServerName" /etc/apache2/sites-available/default-ssl.conf; then
    sed -i "/DocumentRoot/a \ \ \ \ ServerName ${DOMAIN}" /etc/apache2/sites-available/default-ssl.conf
fi

# Vorbereitung der Zertifikats-Pfade
CERT_KEY="/etc/ssl/private/wenomtest-selfsigned.key"
CERT_CRT="/etc/ssl/certs/wenomtest-selfsigned.crt"
SERVER_IP=$(hostname -I | awk '{print $1}')

echo "Generiere selbstsigniertes Zertifikat..."

if [ "$USEIP" = true ]; then
    # Nur IP im Zertifikat
    openssl req -x509 -nodes -days 3650 -newkey rsa:4096 \
        -keyout "$CERT_KEY" -out "$CERT_CRT" \
        -subj "/C=DE/ST=NRW/L=NRW/O=NONE/CN=${SERVER_IP}" \
        -addext "subjectAltName = IP:${SERVER_IP}"
else
    # Domain UND IP im Zertifikat (Best Practice)
    openssl req -x509 -nodes -days 3650 -newkey rsa:4096 \
        -keyout "$CERT_KEY" -out "$CERT_CRT" \
        -subj "/C=DE/ST=NRW/L=NRW/O=NONE/CN=${DOMAIN}" \
        -addext "subjectAltName = DNS:${DOMAIN}, IP:${SERVER_IP}"
fi

# Apache auf die neuen Zertifikats-Dateien hinweisen
sed -i "s|SSLCertificateFile.*|SSLCertificateFile ${CERT_CRT}|" /etc/apache2/sites-available/default-ssl.conf
sed -i "s|SSLCertificateKeyFile.*|SSLCertificateKeyFile ${CERT_KEY}|" /etc/apache2/sites-available/default-ssl.conf

# Apache testen und neustarten
apache2ctl configtest
systemctl restart apache2
systemctl restart php${PHPVERSION}-fpm

# Download und Entpacken 
echo "Download und Entpacken Wenom"
mkdir -p -v $INSTALLPATH 
cd $INSTALLPATH
wget -N https://github.com/SVWS-NRW/SVWS-Server/releases/download/v${SVWSVERSION}/WeNoM-${SVWSVERSION}-Beta.zip
unzip -o *.zip


# Rechte setzen
chmod -R 755 $INSTALLPATH
chown -R www-data:www-data $INSTALLPATH
# DB Verzeichnis braucht Schreibrechte für SQLite
mkdir -p $INSTALLPATH/db
chmod -R 777 $INSTALLPATH/db 

# Erzeugen des Secrets
echo "Generiere Client-Secret..."
# Wir nutzen --insecure (-k), falls das SSL-Zertifikat self-signed ist
curl -k --request GET --url "https://localhost/api/setup" --header "Content-Type: application/x-www-form-urlencoded"

echo -e "\n\nDas Secret für die Synchronisation mit dem SVWS-Server ist:\n"
if [ -f "${INSTALLPATH}/db/client.sec" ]; then
    cat ${INSTALLPATH}/db/client.sec
    SECRET=$(<"${INSTALLPATH}/db/client.sec")
else
    echo "Fehler: client.sec wurde nicht erstellt."
fi

echo -e "\n\n################# Installation auf $DOMAIN beendet! ####################\n"



# Weblupo unter nginx auf Port 80

mkdir -p /var/www/html/weblupo
cd /var/www/html/weblupo
wget -N https://github.com/SVWS-NRW/SVWS-Server/releases/download/v${SVWSVERSION}/SVWS-Laufbahnplanung-${SVWSVERSION}.zip
unzip -o *.zip

# svws-tools einrichten

## SVWS-Conferenz

cd $SCRIPT_DIR

apt install -y nodejs npm 
git clone https://github.com/FPfotenhauer/SVWS-Conference
cd SVWS-Conference

npm i
npm run build

mkdir -p /var/www/html/conference
cp -r dist/* /var/www/html/conference/


cd $SCRIPT_DIR

## svws-Main-Server

git clone https://github.com/FPfotenhauer/SVWS-Main-Server
cd SVWS-Main-Server
cp .env.example .env
sed -i "s/^SVWS_HOST=.*/SVWS_HOST=${SERVER_IP}/" .env

docker compose up --build -d


cd $SCRIPT_DIR

## SVWS-Media

git clone https://github.com/FPfotenhauer/SVWS-Media
cd SVWS-Media
docker compose up -d

## SVWS-Gradehub

git clone https://github.com/FPfotenhauer/SVWS-GradeHub
cd SVWS-GradeHub

npm i
npm run build:web
cp .env.example .env
sed -i 's/ADMINTOOL_VISIBLE=false/ADMINTOOL_VISIBLE=true/' .env
mkdir -p /var/www/html/gradehub
cp -r dist/* /var/www/html/gradehub/

cd $SCRIPT_DIR

## SVWS-Import

git clone https://github.com/SVWS-NRW/SVWS-Import
cd SVWS-Import
npm i 
npm run build
mkdir -p /var/www/html/import
cp -r dist/* /var/www/html/import/


cd $SCRIPT_DIR

## Übersichtsseite auf nginx einrichten 

apt install nginx -y
rm /var/www/html/index.nginx-debian.html
## css download
wget -N -P /var/www/html/ https://www.w3schools.com/w3css/5/w3.css
## nrw Bürgerwappen
wget -N -P /var/www/html/ https://www.land.nrw/media/12370/download
mv /var/www/html/download /var/www/html/logo_nrw.jpg

cat <<EOF > "/var/www/html/index.html"
<!DOCTYPE html>
<html lang="de">
<head>
    <title>SVWS - Testplattform</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="UTF-8">
    <link rel="stylesheet" href="https://www.w3schools.com/w3css/5/w3.css">
    <style>
        .header-bg { background-color: #003462; color: white; }
        .server-link { font-weight: bold; }
    </style>
</head>

<body>

<header class="w3-container header-bg">
    <div class="w3-row">
        <div class="w3-half w3-container">
            <h1><a href="https://www.svws.nrw.de/" style="text-decoration:none;">SVWS-Server</a></h1>
            <h4>Testplattform</h4>
        </div>
        <div class="w3-half w3-container">
            <img src="logo_nrw.jpg" alt="NRW Logo" height="150" class="w3-right w3-padding-16">
        </div>
    </div>
</header>

<main class="w3-container w3-padding-large">
    
    <section>

        <h3>SVWS-Server, WeNoM und WebLupo Test-Instanzen</h3>
        <table class="w3-table w3-bordered w3-hoverable">
            <thead>
                <tr class="w3-light-grey">
                    <th>URL</th>
                    <th>Version</th>
                    <th>Infos</th>
                </tr>
            </thead>

            <tr>
                <td><a href="https://${SERVER_IP}:8443" target="_blank">SVWS-Server</a></td>
	        <td><a href="https://github.com/SVWS-NRW/SVWS-Server/releases">v${SVWSVERSION}</a></td>
                <td></td>
            </tr>

            <tr>
                <td>SchILD-NRW 3</td>
	        <td><a href="https://github.com/SVWS-NRW/Schild-NRW-3/releases">v${SCHILDVERSION}</a></td>
                <td>via Windows (samba) Dateifreigabe</td>
            </tr>

            <tr>
                <td><a href="https://${SERVER_IP}" target="_blank">WeNoM</a></td>
	        <td><a href="https://github.com/SVWS-NRW/SVWS-Server/releases">v${SVWSVERSION}</a></td>
                <td>URL-> &nbsp;  ${SERVER_IP} <br> Secret-> &nbsp; ${SECRET} </td>
            </tr>

            <tr>
                <td><a href="http://${SERVER_IP}/weblupo" target="_blank">WebLuPO</a></td>
	        <td><a href="https://github.com/SVWS-NRW/SVWS-Server/releases">v${SVWSVERSION}</a></td>
                <td></td>
            </tr>

        </table>
    </section>      
    <section>      

        <h3>SVWS-Tools</h3>
        <table class="w3-table w3-bordered w3-hoverable">
            <thead>
                <tr class="w3-light-grey">
                    <th>URL</th>
                    <th>Version</th>
                    <th>Infos</th>
                </tr>
            </thead>
           
            <tr>
                <td><a href="http://${SERVER_IP}/conference" target="_blank">SVWS-Conference</a></td>
                <td><a href="https://github.com/FPfotenhauer/SVWS-Conference">Beta<a></td>
                <td></td>
            </tr>

            <tr>
                <td><a href="http://${SERVER_IP}/import" target="_blank">SVWS-Import</a></td>
                <td><a href="https://github.com/SVWS-NRW/SVWS-Import">Beta<a></td>
                <td></td>
            </tr>


            <tr>
                <td><a href="http://${SERVER_IP}:8081" target="_blank">SVWS-Main-Server</a></td>
                <td><a href="https://github.com/FPfotenhauer/SVWS-Main-Server">Beta<a></td>
                <td></td>
            </tr>
            <tr>
                <td><a href="http://${SERVER_IP}:8080" target="_blank">SVWS-Media</a></td>
                <td><a href="https://github.com/FPfotenhauer/SVWS-Media">Beta<a></td>
                <td>Login: Uder: Admin PW: admin</td>
            </tr>
            <tr>
                <td><a href="http://${SERVER_IP}/gradehub" target="_blank">SVWS-GradeHub</a></td>
                <td><a href="https://github.com/FPfotenhauer/SVWS-GradeHub">Beta<a></td>
                <td></td>
            </tr>


        </table>

    </section>       

</main>

</body>
</html>

EOF


# SVWS Schulunggsdatendanken holen
cd $SCRIPT_DIR
SCHEMA_USER="svwsadmin"
SCHEMA_PW=$PASSWORD
MARIADB_ROOT_PW=$PASSWORD

wget -O TestDB.sqlite ${TESTDB_SQLITE} 


CURL_CMD="curl --user \"root:${MARIADB_ROOT_PW}\" -k -s -o /dev/null -w \"%{http_code}\" \
  -X POST \"https://${SERVER_IP}:${SVWSPORTNUMBER}/api/schema/root/import/sqlite/svwsdb\" \
  -H 'accept: application/json' \
  -H 'Content-Type: multipart/form-data' \
  -F \"database=@${SCRIPT_DIR}/TestDB.sqlite\" \
  -F \"schemaUsername=${SCHEMA_USER}\" \
  -F \"schemaUserPassword=${SCHEMA_PW}\""

echo "Importiere die TestDatenbank:"
echo "${CURL_CMD}"

HTTP_CODE=$(eval "${CURL_CMD}")


# Testdatenbank verschieben in die Windowsfreigabe
mkdir -p "$FOLDER/volume/samba/storage/schulungsunterlagen/testdbs/"
mv *.sqlite "$FOLDER/volume/samba/storage/schulungsunterlagen/testdbs/"

