#!/usr/bin/env bash
set -euo pipefail

if [ "$(id -u)" -ne 0 ]; then
  echo "Bitte mit sudo starten: sudo bash install.sh"
  exit 1
fi

APP_SOURCE="$(cd "$(dirname "$0")" && pwd)/www"
APP_TARGET="/var/www/gesundheitsbelege"
DATA_TARGET="/var/lib/gesundheitsbelege"
BACKUP_TARGET="/var/backups/gesundheitsbelege"

echo "Apache, PHP und SQLite werden installiert ..."
apt-get update
apt-get install -y apache2 cron sudo php php-cli php-sqlite3 php-mbstring php-fileinfo php-curl php-gd php-zip sqlite3 apache2-utils poppler-utils img2pdf webp acl xdg-utils util-linux

APP_USER=""
if [ ! -f "$DATA_TARGET/.htpasswd" ]; then
  read -r -p "Benutzername für die Webseite [tom]: " APP_USER
  APP_USER="${APP_USER:-tom}"
  while true; do
    read -r -s -p "Passwort für die Webseite: " APP_PASSWORD
    echo
    read -r -s -p "Passwort wiederholen: " APP_PASSWORD_2
    echo
    [ "$APP_PASSWORD" = "$APP_PASSWORD_2" ] && [ -n "$APP_PASSWORD" ] && break
    echo "Die Passwörter stimmen nicht überein oder sind leer. Bitte erneut eingeben."
  done
fi

install -d -m 0755 "$APP_TARGET"
install -d -o www-data -g www-data -m 0750 "$DATA_TARGET" "$DATA_TARGET/uploads" "$DATA_TARGET/previews" "$DATA_TARGET/tmp" "$DATA_TARGET/safety-backups" "$DATA_TARGET/documents" "$DATA_TARGET/files"
install -d -o root -g www-data -m 0750 "$BACKUP_TARGET"
if [ ! -f /var/lib/gesundheitsbelege.location ]; then echo "$DATA_TARGET" > /var/lib/gesundheitsbelege.location; fi
chown www-data:www-data /var/lib/gesundheitsbelege.location
chmod 0660 /var/lib/gesundheitsbelege.location
cp -a "$APP_SOURCE/." "$APP_TARGET/"
chown -R root:www-data "$APP_TARGET"
find "$APP_TARGET" -type d -exec chmod 0755 {} \;
find "$APP_TARGET" -type f -exec chmod 0644 {} \;
install -o root -g root -m 0755 "$APP_SOURCE/../scripts/grant-import-read.sh" /usr/local/sbin/gesundheitsbelege-grant-import-read
cat > /etc/sudoers.d/gesundheitsbelege-import <<'SUDOERS'
www-data ALL=(root) NOPASSWD: /usr/local/sbin/gesundheitsbelege-grant-import-read *
SUDOERS
chmod 0440 /etc/sudoers.d/gesundheitsbelege-import
visudo -cf /etc/sudoers.d/gesundheitsbelege-import >/dev/null

if [ ! -f "$DATA_TARGET/.htpasswd" ]; then
  htpasswd -bBc "$DATA_TARGET/.htpasswd" "$APP_USER" "$APP_PASSWORD"
else
  echo "Vorhandene Benutzer und Passwörter bleiben erhalten."
fi
chown www-data:www-data "$DATA_TARGET/.htpasswd"
chmod 0640 "$DATA_TARGET/.htpasswd"

cat > /etc/apache2/conf-available/gesundheitsbelege.conf <<'APACHE'
Alias /gesundheitsbelege /var/www/gesundheitsbelege
<Directory /var/www/gesundheitsbelege>
    Options -Indexes
    AllowOverride None
    Require valid-user
    AuthType Basic
    AuthName "Gesundheitsbelege"
    AuthUserFile /var/lib/gesundheitsbelege/.htpasswd
</Directory>
<Directory /var/lib/gesundheitsbelege>
    Require all denied
</Directory>
APACHE

a2enconf gesundheitsbelege
phpenmod sqlite3
PHP_APACHE_CONF="$(find /etc/php -type d -path '*/apache2/conf.d' | head -n 1)"
if [ -n "$PHP_APACHE_CONF" ]; then
  cat > "$PHP_APACHE_CONF/99-gesundheitsbelege.ini" <<'PHPINI'
upload_max_filesize=100M
post_max_size=105M
max_file_uploads=200
max_execution_time=180
PHPINI
fi
systemctl enable --now apache2
systemctl enable --now cron
systemctl reload apache2

cat > /usr/local/sbin/gesundheitsbelege-backup <<'BACKUP'
#!/usr/bin/env bash
set -Eeuo pipefail
TARGET="/var/backups/gesundheitsbelege"
STAMP="$(date +%Y-%m-%d_%H-%M-%S)"
DATA_PATH="$(cat /var/lib/gesundheitsbelege.location 2>/dev/null || echo /var/lib/gesundheitsbelege)"
STATUS_PATH="$DATA_PATH/backup-status.json"
ERROR_PATH="$DATA_PATH/backup-error.txt"
ARCHIVE="$TARGET/gesundheitsbelege_$STAMP.tar.gz"
PARTIAL="$TARGET/.gesundheitsbelege_$STAMP.partial"
STAGE=""

exec 9>/run/lock/gesundheitsbelege-backup.lock
if ! flock -n 9; then
  echo "Eine Sicherung läuft bereits."
  exit 0
fi

cleanup_error() {
  local exit_code=$?
  [ -n "$STAGE" ] && rm -rf -- "$STAGE"
  rm -f -- "$PARTIAL"
  if [ "$exit_code" -ne 0 ]; then
    install -d -o www-data -g www-data -m 0750 "$DATA_PATH"
    date --iso-8601=seconds > "$ERROR_PATH"
    chown www-data:www-data "$ERROR_PATH"
    chmod 0640 "$ERROR_PATH"
    echo "Sicherung fehlgeschlagen." >&2
  fi
  exit "$exit_code"
}
trap cleanup_error EXIT

install -d -o root -g www-data -m 0750 "$TARGET"
install -d -o www-data -g www-data -m 0750 "$DATA_PATH"
STAGE="$(mktemp -d /tmp/gesundheitsbelege-backup.XXXXXX)"
BACKUP_ROOT="$STAGE/gesundheitsbelege"
install -d -m 0750 "$BACKUP_ROOT"

if [ -f "$DATA_PATH/gesundheitsbelege.sqlite" ]; then
  sqlite3 "$DATA_PATH/gesundheitsbelege.sqlite" ".backup '$BACKUP_ROOT/gesundheitsbelege.sqlite'"
fi
for directory in uploads previews documents files; do
  if [ -d "$DATA_PATH/$directory" ]; then
    cp -a "$DATA_PATH/$directory" "$BACKUP_ROOT/$directory"
  fi
done
if [ -f /var/lib/gesundheitsbelege/.htpasswd ]; then
  cp -a /var/lib/gesundheitsbelege/.htpasswd "$BACKUP_ROOT/.htpasswd"
fi
cat > "$BACKUP_ROOT/backup-info.txt" <<INFO
Gesundheitsbelege Version 12.4.1
Erstellt: $(date --iso-8601=seconds)
Enthält: Datenbank, Belege, Vorschauen, Dokumente, Dateien und Benutzerzugänge
INFO

tar -czf "$PARTIAL" -C "$STAGE" gesundheitsbelege
mv "$PARTIAL" "$ARCHIVE"
chown root:www-data "$ARCHIVE"
chmod 0640 "$ARCHIVE"
find "$TARGET" -type f -name 'gesundheitsbelege_*.tar.gz' -mtime +90 -delete

STATUS_TMP="$DATA_PATH/.backup-status.$$"
CREATED_AT="$(date --iso-8601=seconds)"
FILE_SIZE="$(stat -c %s "$ARCHIVE")"
printf '{"created_at":"%s","file_name":"%s","file_size":%s}\n' \
  "$CREATED_AT" "$(basename "$ARCHIVE")" "$FILE_SIZE" > "$STATUS_TMP"
chown www-data:www-data "$STATUS_TMP"
chmod 0640 "$STATUS_TMP"
mv "$STATUS_TMP" "$STATUS_PATH"
rm -f -- "$ERROR_PATH"

rm -rf -- "$STAGE"
STAGE=""
trap - EXIT
echo "Sicherung erstellt: $ARCHIVE"
BACKUP
chmod 0750 /usr/local/sbin/gesundheitsbelege-backup

cat > /etc/cron.d/gesundheitsbelege-backup <<'CRON'
30 2 * * * root /usr/local/sbin/gesundheitsbelege-backup >/dev/null 2>&1
CRON
chmod 0644 /etc/cron.d/gesundheitsbelege-backup

CURRENT_DATA_PATH="$(cat /var/lib/gesundheitsbelege.location 2>/dev/null || echo "$DATA_TARGET")"
if [ -f "$CURRENT_DATA_PATH/gesundheitsbelege.sqlite" ]; then
  echo "Erste automatische Sicherung wird erstellt ..."
  if ! /usr/local/sbin/gesundheitsbelege-backup; then
    echo "Hinweis: Die erste Sicherung ist fehlgeschlagen. Die Webseite erinnert daran und der nächste Versuch erfolgt nachts."
  fi
fi

cat > /etc/cron.d/gesundheitsbelege-google-tasks <<'CRON'
*/5 * * * * www-data /usr/bin/php /var/www/gesundheitsbelege/google_tasks_cron.php >/dev/null 2>&1
CRON
chmod 0644 /etc/cron.d/gesundheitsbelege-google-tasks

echo
echo "Installation abgeschlossen."
echo "Gesundheitsbelege Version 12.4.1"
echo "Öffne: http://raspberrypi.local/gesundheitsbelege/"
if [ -n "$APP_USER" ]; then echo "Benutzer: $APP_USER"; fi
