#!/bin/sh
set -eu
umask 077

REQUEST="/path/to/olivetin/export/device-sync/device-lifecycle.request"
CSV="/path/to/olivetin/config/geraeteliste.csv"
CHECK="/path/to/olivetin/config/scripts/pruefe-geraeteliste.sh"
GENERATOR="/path/to/olivetin/config/scripts/geraeteliste-zu-entities.sh"
STATUS="/path/to/olivetin/export/device-sync/device-lifecycle.status"
LOCK="/tmp/olivetin-device-lifecycle.lock"

if [ ! -e "$REQUEST" ]; then
  echo "[BEREIT] Kein Lebenszyklus-Auftrag vorhanden."
  exit 0
fi

if [ ! -f "$CSV" ]; then
  echo "[STOPP] Geräteliste fehlt: $CSV"
  exit 66
fi

CSV_OWNER="$(stat -c '%u:%g' "$CSV")"
CSV_MODE="$(stat -c '%a' "$CSV")"

mkdir "$LOCK" 2>/dev/null || {
  echo "[STOPP] Eine Lebenszyklus-Verarbeitung laeuft bereits."
  exit 65
}

trap 'rmdir "$LOCK" 2>/dev/null || true' EXIT HUP INT TERM

ACTION="$(cut -d';' -f1 "$REQUEST")"
TMP="${CSV}.tmp.$$"
BACKUP="${CSV}.bak-before-lifecycle-$(date +%Y%m%d-%H%M%S)"


case "$ACTION" in
  deaktivieren)
    IFS=';' read -r \
      ACTION ID NAME IP MAC VPN DIRECT ACTIVE GRUND < "$REQUEST"

    [ "$ACTIVE" = "ja" ] || {
      echo "[STOPP] Auftrag erwartet ein aktives Geraet."
      exit 65
    }

    MATCHES="$(awk -F';' \
      -v id="$ID" \
      -v name="$NAME" \
      -v ip="$IP" \
      -v mac="$MAC" '
    NR > 1 &&
    $1 == id &&
    $2 == name &&
    $3 == ip &&
    toupper($4) == toupper(mac) &&
    $7 == "ja" {
      n++
    }

    END {
      print n+0
    }
    ' "$CSV")"

    [ "$MATCHES" -eq 1 ] || {
      echo "[STOPP] Aktiver CSV-Datensatz stimmt nicht mehr."
      exit 65
    }

    awk -F';' -v OFS=';' -v id="$ID" '
    $1 == id {
      $7="nein"
    }

    { print }
    ' "$CSV" > "$TMP"
    ;;

  reaktivieren)
    IFS=';' read -r \
      ACTION ID OLD_NAME OLD_IP MAC \
      NEW_NAME NEW_IP VPN DIRECT < "$REQUEST"

    MATCHES="$(awk -F';' \
      -v id="$ID" \
      -v name="$OLD_NAME" \
      -v ip="$OLD_IP" \
      -v mac="$MAC" '
    NR > 1 &&
    $1 == id &&
    $2 == name &&
    $3 == ip &&
    toupper($4) == toupper(mac) &&
    $7 == "nein" {
      n++
    }

    END {
      print n+0
    }
    ' "$CSV")"

    [ "$MATCHES" -eq 1 ] || {
      echo "[STOPP] Inaktiver CSV-Datensatz stimmt nicht mehr."
      exit 65
    }

    awk -F';' -v OFS=';' \
      -v id="$ID" \
      -v new_name="$NEW_NAME" \
      -v new_ip="$NEW_IP" '
    $1 == id {
      $2=new_name
      $3=new_ip
      $7="ja"
    }

    { print }
    ' "$CSV" > "$TMP"
    ;;

  *)
    echo "[STOPP] Unbekannte Lebenszyklus-Aktion."
    exit 64
    ;;
esac

/bin/sh "$CHECK" "$TMP"
cp -p "$CSV" "$BACKUP"
find "$(dirname "$CSV")" -maxdepth 1 -type f -name "geraeteliste.csv.bak-before-lifecycle-*" -print | sort | awk '{f[NR]=$0} END {for(i=1;i<=NR-20;i++) print f[i]}' | xargs -r rm -f

cat "$TMP" > "$CSV"
rm -f "$TMP"

chown "$CSV_OWNER" "$CSV"
chmod "$CSV_MODE" "$CSV"

if ! "$GENERATOR"; then
  cat "$BACKUP" > "$CSV"
  "$GENERATOR" >/dev/null 2>&1 || true
  echo "[STOPP] Entity-Erzeugung fehlgeschlagen; CSV zurueckgesetzt."
  exit 66
fi

if ! docker exec olivetin-container /bin/sh \
  /config/scripts/synchronisiere-geraeteliste.sh; then

  cat "$BACKUP" > "$CSV"
  chown "$CSV_OWNER" "$CSV"
  chmod "$CSV_MODE" "$CSV"

  "$GENERATOR" >/dev/null 2>&1 || true

  docker exec olivetin-container /bin/sh \
    /config/scripts/synchronisiere-geraeteliste.sh \
    >/dev/null 2>&1 || true

  echo "[STOPP] Synchronisierung fehlgeschlagen; alter CSV-Stand wieder aktiv."
  exit 67
fi

DONE="${REQUEST}.processed-$(date +%Y%m%d-%H%M%S)"
mv "$REQUEST" "$DONE"

{
  echo "RESULT=OK"
  echo "ACTION=$ACTION"
  echo "ID=$ID"
  echo "BACKUP=$BACKUP"
  sha256sum "$CSV"
} > "$STATUS"

if docker restart olivetin-container >/dev/null 2>&1; then
  echo "OLIVETIN_RESTART=OK" >> "$STATUS"
else
  echo "OLIVETIN_RESTART=FEHLER" >> "$STATUS"
  echo "[STOPP] Lebenszyklus erfolgreich, aber OliveTin-Neustart fehlgeschlagen."
  cat "$STATUS"
  exit 68
fi

echo "[OK] Lebenszyklus-Auftrag verarbeitet."
cat "$STATUS"