#!/usr/bin/env bash
#
# DataMetric360 — Installation in Home Assistant
#
# Richtet das Panel samt Backend auf einer Home-Assistant-Instanz ein und
# verdrahtet die Selbstaktualisierung, damit danach alles Weitere über die
# Weboberfläche läuft: Sensoren zuordnen, nach Updates suchen, einspielen.
#
# Wo ausführen:
#   Am einfachsten direkt auf der HA-Instanz, im Add-on "Terminal & SSH":
#     bash <(curl -fsSL <ROH-URL dieser Datei>)
#   Alternativ von einem Rechner aus gegen ein eingebundenes config-Verzeichnis:
#     ./install.sh --ziel /Volumes/config
#
# Mehrfach ausführbar: bereits vorhandene Fahrzeugdaten werden nie
# überschrieben, und der Abschnitt in der configuration.yaml wird beim
# erneuten Lauf ersetzt statt ein zweites Mal angehängt.
#
set -euo pipefail

# ------------------------------------------------------------ Voreinstellungen

REPO_STANDARD="https://gitea.nothaft.cloud/paul/audi-app.git"
BRANCH="main"
ZIEL="/config"
QUELLE=""
TOKEN=""
REPO="$REPO_STANDARD"
PYSCRIPT_INSTALLIEREN="ja"
INTERAKTIV="ja"

MARKE_START="# >>> DataMetric360 (von install.sh verwaltet) >>>"
MARKE_ENDE="# <<< DataMetric360 <<<"

# ------------------------------------------------------------------- Ausgabe

rot()  { printf '\033[31m%s\033[0m\n' "$*"; }
gruen(){ printf '\033[32m%s\033[0m\n' "$*"; }
grau() { printf '\033[90m%s\033[0m\n' "$*"; }
schritt(){ printf '\n\033[1m==> %s\033[0m\n' "$*"; }
fehler(){ rot "FEHLER: $*"; exit 1; }

hilfe() {
  cat <<'ENDE'
DataMetric360 — Installation in Home Assistant

  --ziel <pfad>      config-Verzeichnis von Home Assistant (Standard: /config)
  --von <pfad>       lokale Arbeitskopie benutzen statt zu klonen
  --repo <url>       Repository zum Klonen und für die Selbstaktualisierung
  --branch <name>    Branch (Standard: main)
  --token <wert>     langlebiges Zugriffstoken für die Kilometerstand-Historie
  --ohne-pyscript    pyscript nicht mitinstallieren (wenn schon vorhanden)
  --still            keine Rückfragen stellen (für unbeaufsichtigte Läufe)
  --hilfe            diese Übersicht

Beispiele
  bash install.sh                          # auf der HA-Instanz, klont selbst
  bash install.sh --von ~/audi-app         # aus einer lokalen Arbeitskopie
  bash install.sh --ziel /Volumes/config   # gegen ein eingebundenes Laufwerk
ENDE
}

while [ $# -gt 0 ]; do
  case "$1" in
    --ziel) ZIEL="${2:-}"; shift 2 ;;
    --von) QUELLE="${2:-}"; shift 2 ;;
    --repo) REPO="${2:-}"; shift 2 ;;
    --branch) BRANCH="${2:-}"; shift 2 ;;
    --token) TOKEN="${2:-}"; shift 2 ;;
    --ohne-pyscript) PYSCRIPT_INSTALLIEREN="nein"; shift ;;
    --still) INTERAKTIV="nein"; shift ;;
    --hilfe|-h) hilfe; exit 0 ;;
    *) fehler "Unbekannte Option: $1 (--hilfe zeigt alle)" ;;
  esac
done

# --------------------------------------------------------------- Vorprüfungen

schritt "Umgebung prüfen"

for werkzeug in python3 curl unzip; do
  command -v "$werkzeug" >/dev/null 2>&1 || fehler "$werkzeug wird gebraucht, ist aber nicht vorhanden."
done

[ -d "$ZIEL" ] || fehler "Das Zielverzeichnis $ZIEL gibt es nicht. Mit --ziel den richtigen Pfad angeben."
[ -w "$ZIEL" ] || fehler "Keine Schreibrechte auf $ZIEL."

if [ ! -f "$ZIEL/configuration.yaml" ]; then
  rot "In $ZIEL liegt keine configuration.yaml."
  fehler "Das sieht nicht nach einem Home-Assistant-Verzeichnis aus. Pfad mit --ziel prüfen."
fi
grau "  Ziel: $ZIEL"

# ------------------------------------------------------------ Quelle besorgen

AUFRAEUMEN=""
saeubern() { [ -n "$AUFRAEUMEN" ] && rm -rf "$AUFRAEUMEN" || true; }
trap saeubern EXIT

if [ -n "$QUELLE" ]; then
  schritt "Lokale Arbeitskopie benutzen"
  [ -d "$QUELLE/homeassistant" ] || fehler "In $QUELLE gibt es keinen Ordner homeassistant/."
  HA_QUELLE="$QUELLE/homeassistant"
  grau "  $HA_QUELLE"
else
  schritt "Projekt herunterladen"
  command -v git >/dev/null 2>&1 || fehler "git wird zum Klonen gebraucht (oder --von <pfad> benutzen)."
  AUFRAEUMEN="$(mktemp -d)"
  if ! git clone --depth 1 --branch "$BRANCH" "$REPO" "$AUFRAEUMEN/quelle" >/dev/null 2>&1; then
    rot "Klonen von $REPO fehlgeschlagen."
    grau "  Bei einem privaten Repository ein Zugangstoken in die URL aufnehmen, etwa:"
    grau "  --repo https://<nutzer>:<token>@gitea.example/paul/audi-app.git"
    exit 1
  fi
  HA_QUELLE="$AUFRAEUMEN/quelle/homeassistant"
  grau "  $REPO ($BRANCH)"
fi

[ -d "$HA_QUELLE/pyscript" ] || fehler "Im Projekt fehlt homeassistant/pyscript/."

# ------------------------------------------------------------------- pyscript

if [ "$PYSCRIPT_INSTALLIEREN" = "ja" ]; then
  if [ -d "$ZIEL/custom_components/pyscript" ]; then
    schritt "pyscript ist bereits vorhanden"
    grau "  $ZIEL/custom_components/pyscript"
  else
    schritt "pyscript installieren"
    VERSION="$(curl -fsSL https://api.github.com/repos/custom-components/pyscript/releases/latest \
      | python3 -c 'import json,sys; print(json.load(sys.stdin)["tag_name"])' 2>/dev/null || true)"
    [ -n "$VERSION" ] || fehler "Konnte die neueste pyscript-Version nicht ermitteln (kein Internet?)."
    TMPPY="$(mktemp -d)"
    curl -fsSL -o "$TMPPY/pyscript.zip" \
      "https://github.com/custom-components/pyscript/archive/refs/tags/${VERSION}.zip"
    unzip -oq "$TMPPY/pyscript.zip" -d "$TMPPY"
    mkdir -p "$ZIEL/custom_components"
    cp -r "$TMPPY/pyscript-${VERSION}/custom_components/pyscript" "$ZIEL/custom_components/"
    rm -rf "$TMPPY"
    gruen "  pyscript $VERSION installiert"
  fi
fi

# --------------------------------------------------------- Dateien einspielen

schritt "Backend und Oberfläche einspielen"

mkdir -p "$ZIEL/pyscript" "$ZIEL/www" "$ZIEL/audi_dashboard"

# pyscript und www sind Code - vollständig ersetzen.
cp -r "$HA_QUELLE/pyscript/." "$ZIEL/pyscript/"
cp -r "$HA_QUELLE/www/." "$ZIEL/www/"
grau "  pyscript/ und www/ aktualisiert"

# Der Belegleser liegt in data/, ist aber Code (belegverarbeitung.py ruft ihn
# als Unterprozess auf) - deshalb hier mit, anders als die Datenbestände.
cp "$HA_QUELLE/data/shell_beleg_parser.py" "$ZIEL/audi_dashboard/shell_beleg_parser.py"

# Datenbestände: nur anlegen, was fehlt. Vorhandenes nie überschreiben.
if [ ! -f "$ZIEL/audi_dashboard/fahrzeugprofil.json" ]; then
  cp "$HA_QUELLE/data/fahrzeugprofil.example.json" "$ZIEL/audi_dashboard/fahrzeugprofil.json"
  gruen "  Fahrzeugprofil aus der Vorlage angelegt"
else
  grau "  Fahrzeugprofil vorhanden - unangetastet"
fi
for datei in fahrten.jsonl tankvorgaenge.jsonl; do
  [ -f "$ZIEL/audi_dashboard/$datei" ] || : > "$ZIEL/audi_dashboard/$datei"
done
mkdir -p "$ZIEL/audi_dashboard/belege"

# --------------------------------------------------- Selbstaktualisierung

schritt "Selbstaktualisierung verdrahten"

# UPDATE_REPO_URL im ausgelieferten einstellungen.py setzen, damit
# "Update suchen" in den Einstellungen der App funktioniert.
python3 - "$ZIEL/pyscript/modules/einstellungen.py" "$REPO" "$BRANCH" <<'PYENDE'
import re, sys
pfad, repo, branch = sys.argv[1], sys.argv[2], sys.argv[3]
with open(pfad, encoding="utf-8") as f:
    inhalt = f.read()
inhalt = re.sub(r'^UPDATE_REPO_URL\s*=.*$', f'UPDATE_REPO_URL = "{repo}"', inhalt, count=1, flags=re.M)
inhalt = re.sub(r'^UPDATE_BRANCH\s*=.*$', f'UPDATE_BRANCH = "{branch}"', inhalt, count=1, flags=re.M)
with open(pfad, "w", encoding="utf-8") as f:
    f.write(inhalt)
PYENDE
grau "  Updatequelle: $REPO ($BRANCH)"
grau "  Danach in der App unter Einstellungen → Version → \"Update suchen\""

# ---------------------------------------------------------- configuration.yaml

schritt "configuration.yaml ergänzen"

KONFIG="$ZIEL/configuration.yaml"
SICHERUNG="$KONFIG.vor-datametric360-$(date +%Y%m%d_%H%M%S)"
cp "$KONFIG" "$SICHERUNG"
grau "  Sicherung: $(basename "$SICHERUNG")"

python3 - "$KONFIG" "$MARKE_START" "$MARKE_ENDE" <<'PYENDE'
import re, sys
pfad, start, ende = sys.argv[1], sys.argv[2], sys.argv[3]
with open(pfad, encoding="utf-8") as f:
    inhalt = f.read()

block = f"""{start}
# Von install.sh eingefügt. Aenderungen innerhalb dieses Abschnitts werden bei
# der naechsten Installation ersetzt - Eigenes bitte ausserhalb notieren.
pyscript:
  allow_all_imports: true

panel_custom:
  - name: audi-dashboard-panel
    sidebar_title: Mein Audi
    sidebar_icon: mdi:car-sports
    module_url: /local/audi-dashboard-panel.js?v=1
    embed_iframe: false
    trust_external_script: false
{ende}"""

muster = re.compile(re.escape(start) + r".*?" + re.escape(ende), re.S)
if muster.search(inhalt):
    inhalt = muster.sub(block, inhalt)
    print("  Abschnitt ersetzt")
else:
    for schluessel in ("pyscript:", "panel_custom:"):
        if re.search(rf"^{schluessel}", inhalt, re.M):
            print(f"  ACHTUNG: '{schluessel}' steht bereits ausserhalb des verwalteten Abschnitts.")
            print("           Der Abschnitt wird trotzdem angehaengt - Home Assistant meldet dann")
            print("           einen doppelten Schluessel. Bitte den alten Eintrag von Hand entfernen.")
    if not inhalt.endswith("\n"):
        inhalt += "\n"
    inhalt += "\n" + block + "\n"
    print("  Abschnitt angehaengt")

with open(pfad, "w", encoding="utf-8") as f:
    f.write(inhalt)
PYENDE

# ------------------------------------------------------------------- Token

schritt "Zugriffstoken für die Kilometerstand-Historie"

TOKENDATEI="$ZIEL/audi_dashboard/ha_token.txt"
if [ -n "$TOKEN" ]; then
  printf '%s' "$TOKEN" > "$TOKENDATEI"
  chmod 600 "$TOKENDATEI" 2>/dev/null || true
  gruen "  Token gespeichert"
elif [ -s "$TOKENDATEI" ]; then
  grau "  Vorhandenes Token bleibt unangetastet"
elif [ "$INTERAKTIV" = "ja" ] && [ -t 0 ]; then
  echo "  Der Fahrtabschluss liest den Kilometerstand aus dem Verlauf und braucht dafür"
  echo "  ein langlebiges Zugriffstoken (Profil → Sicherheit → Langlebige Zugriffstoken)."
  echo "  Leer lassen und später nachtragen ist möglich - Fahrten bleiben dann ohne Strecke."
  printf "  Token (Eingabe bleibt verborgen): "
  read -rs EINGABE || EINGABE=""
  echo
  if [ -n "$EINGABE" ]; then
    printf '%s' "$EINGABE" > "$TOKENDATEI"
    chmod 600 "$TOKENDATEI" 2>/dev/null || true
    gruen "  Token gespeichert"
  else
    rot "  Übersprungen - später in $TOKENDATEI ablegen."
  fi
else
  rot "  Kein Token angegeben. Später in $TOKENDATEI ablegen,"
  rot "  sonst bleiben Fahrten ohne Streckenangabe."
fi

# ------------------------------------------------------------------ Abschluss

schritt "Fertig"
cat <<ENDE

  Noch zu tun, alles in der Weboberfläche:

  1. Home Assistant neu starten
     Einstellungen → System → oben rechts → Neu starten

  2. Sensoren zuordnen
     Mein Audi → Einstellungen → Fahrzeug einrichten → Einrichten
       → "Setup — Sensoren zuordnen"
     Pflicht ist nur die Zündung; alles Weitere ist optional.

  3. Fahrzeugdaten eintragen
     Im selben Menü unter "Einrichten": Kennzeichen, FIN, Versicherung, …

  Ab dann läuft alles über die Oberfläche - auch Updates:
     Mein Audi → Einstellungen → Version → "Update suchen"

  Sicherung der configuration.yaml:
     $SICHERUNG

ENDE
gruen "Installation abgeschlossen."
