{% extends "tesm_core/base.html" %}
{% from "tesm_core/macros.html" import alert, pill, stat %}

{% block page_title %}Diagnose{% endblock %}
{% block page_sub %}Schemastand, Protokollintegritaet, Schluessel und Systemzugriff{% endblock %}

{% block content %}
<div class="grid grid--4">
  {{ stat('Benutzer', counts['Benutzer']) }}
  {{ stat('Gruppen', counts['Gruppen']) }}
  {{ stat('Aktive Sitzungen', counts['Aktive Sitzungen']) }}
  {{ stat('Protokollzeilen', counts['Protokollzeilen']) }}
</div>

<div class="grid grid--2">
  <section class="card {{ 'card--danger' if not chain.ok }}">
    <div class="card__header">
      <div class="flex-1">
        <div class="card__title">
          {{ icon('shield', size=17) }} Aenderungsprotokoll
          {% if chain.ok %}{{ pill('unversehrt', 'online') }}{% else %}{{ pill('Kette gebrochen', 'danger') }}{% endif %}
        </div>
        <div class="card__sub">{{ chain.checked }} Zeilen geprueft (Hash-Kette)</div>
      </div>
    </div>
    <div class="card__body">
      {% if chain.ok %}
        <p class="muted fs-sm">
          Jede Zeile bindet den Hash ihrer Vorgaengerin ein. Eine nachtraeglich entfernte oder
          geaenderte Zeile wuerde hier auffallen.
        </p>
      {% else %}
        {{ alert(chain.reason ~ ' Erster Bruch bei Eintrag ' ~ chain.broken_at ~ '.', 'danger',
                 'Manipulation oder Datenverlust') }}
      {% endif %}
    </div>
  </section>

  <section class="card {{ 'card--danger' if key_problems }}">
    <div class="card__header">
      <div class="flex-1">
        <div class="card__title">
          {{ icon('key', size=17) }} Schluessel und Dateirechte
          {% if key_problems %}{{ pill('Problem', 'danger') }}{% else %}{{ pill('in Ordnung', 'online') }}{% endif %}
        </div>
        <div class="card__sub">Aktiver Datenschluessel: {{ keystore_active }} (vorhanden: {{ keystore_keys | join(', ') }})</div>
      </div>
      {% if current_user.is_admin %}
        <form method="post" action="{{ url_for('diagnostics.rotate_keys') }}" data-no-guard>
          <input type="hidden" name="{{ csrf_field_name }}" value="{{ csrf_token() }}">
          <button class="btn btn--sm" type="submit"
                  data-confirm="Neuen Datenschluessel anlegen und gespeicherte Geheimnisse neu verschluesseln? Der alte Schluessel bleibt zum Lesen erhalten."
                  data-confirm-title="Schluessel rotieren" data-confirm-ok="Rotieren" data-confirm-style="primary">
            {{ icon('refresh', size=14) }} Rotieren
          </button>
        </form>
      {% endif %}
    </div>
    <div class="card__body">
      {% if key_problems %}
        <ul class="stack stack--tight fs-sm danger-text">
          {% for problem in key_problems %}<li>{{ problem }}</li>{% endfor %}
        </ul>
      {% else %}
        <p class="muted fs-sm">
          Alle Schluesseldateien liegen mit Modus 0600. Feldverschluesselung ist AES-256-GCM mit
          rotierbarem Schluesselbund; jedes Chiffrat ist an seinen Verwendungszweck gebunden.
        </p>
      {% endif %}
    </div>
  </section>
</div>

<section class="card">
  <div class="card__header">
    <div class="flex-1">
      <div class="card__title">{{ icon('database', size=17) }} Schemastand</div>
      <div class="card__sub">
        {{ db_path }} &middot; {{ db_size | bytes }} &middot; {{ migrations | length }} angewendete Migrationen
      </div>
    </div>
  </div>
  <div class="table-wrap">
    <table class="table table--compact" data-behavior="sortable">
      <thead>
        <tr>
          <th class="sortable">Komponente</th>
          <th class="sortable numeric">Version</th>
          <th class="sortable">Migration</th>
          <th>Pruefsumme</th>
          <th class="sortable">Angewendet</th>
        </tr>
      </thead>
      <tbody>
        {% for entry in migrations %}
          <tr>
            <td class="fw-600">{{ entry.component }}</td>
            <td class="numeric">{{ entry.version }}</td>
            <td>{{ entry.name }}</td>
            <td class="mono fs-xs faint">{{ entry.checksum }}</td>
            <td class="fs-sm">{{ entry.applied_at | dt }}</td>
          </tr>
        {% endfor %}
      </tbody>
    </table>
  </div>
</section>

<div class="grid grid--2">
  <section class="card">
    <div class="card__header">
      <div class="flex-1">
        <div class="card__title">
          {{ icon('server', size=17) }} Systemzugriff
          {% if not sysops_available %}{{ pill('nicht verfuegbar', 'warning') }}
          {% elif sysops_selftest and sysops_selftest.ok %}{{ pill('Helfer antwortet', 'online') }}
          {% else %}{{ pill('Helfer antwortet nicht', 'danger') }}{% endif %}
        </div>
        <div class="card__sub">{{ sysops_helper or 'kein Pfad konfiguriert' }}</div>
      </div>
    </div>
    <div class="card__body">
      <p class="muted fs-sm">
        Der Webprozess laeuft unprivilegiert. Alles, was Root-Rechte braucht, geht durch genau
        ein Helferskript mit Positivliste &ndash; nicht durch die Anwendung selbst.
      </p>
      {% if not sysops_available %}
        {{ alert('Ohne Helfer sind Systemaktionen (Dienste, Netzwerk, Zertifikate) deaktiviert.
        Alles andere funktioniert normal -- das ist der erwartete Zustand in einer
        Entwicklungsumgebung.', 'info') }}
      {% elif sysops_selftest and not sysops_selftest.ok %}
        {# Geprueft wird ein echter Aufruf, nicht die blosse Existenz der Datei.
           Genau daran lag es einmal: die Seite meldete "erreichbar", waehrend
           jeder Aufruf scheiterte. #}
        {{ alert(sysops_selftest.message or 'Der Helfer laesst sich nicht aufrufen.',
        'danger', 'Systemaktionen funktionieren nicht') }}
      {% endif %}
    </div>
  </section>

  <section class="card">
    <div class="card__header">
      <div class="flex-1"><div class="card__title">{{ icon('info', size=17) }} Laufzeit</div></div>
      {% if current_user.is_admin %}
        <form method="post" action="{{ url_for('diagnostics.housekeeping') }}" data-no-guard>
          <input type="hidden" name="{{ csrf_field_name }}" value="{{ csrf_token() }}">
          <button class="btn btn--sm" type="submit">{{ icon('refresh', size=14) }} Aufraeumen</button>
        </form>
      {% endif %}
    </div>
    <div class="card__body">
      <dl class="kv fs-sm">
        {% for label, value in runtime.items() %}
          <dt>{{ label }}</dt><dd>{{ value }}</dd>
        {% endfor %}
        <dt>Protokollverzeichnis</dt><dd class="mono">{{ log_dir }}</dd>
      </dl>
    </div>
  </section>
</div>

{% if license_state %}
  <section class="card">
    <div class="card__header">
      <div class="flex-1">
        <div class="card__title">
          {{ icon('key', size=17) }} Lizenzzustand
          {% if license_state.valid and license_state.activated %}{{ pill('aktiv', 'online') }}
          {% elif license_state.valid %}{{ pill('nicht aktiviert', 'warning') }}
          {% else %}{{ pill('ungueltig', 'danger') }}{% endif %}
        </div>
      </div>
    </div>
    <div class="card__body">
      <dl class="kv fs-sm">
        <dt>Datei vorhanden</dt><dd>{{ license_state.present | yes_no }}</dd>
        <dt>Signatur gueltig</dt><dd>{{ license_state.valid | yes_no }}</dd>
        <dt>Aussteller gepinnt</dt><dd>{{ license_state.issuer_pinned | yes_no }}</dd>
        <dt>Rolle</dt><dd>{{ license_state.role }}</dd>
        <dt>Module</dt><dd>{{ license_state.modules | sort | join(', ') or '&ndash;' | safe }}</dd>
        <dt>Letzter Heartbeat</dt><dd>{{ license_state.last_heartbeat_at | dt }}</dd>
        {% if license_state.error %}<dt>Fehler</dt><dd class="danger-text">{{ license_state.error }}</dd>{% endif %}
        {% if license_state.warnings %}
          <dt>Hinweise</dt><dd class="warning-text">{{ license_state.warnings | join('; ') }}</dd>
        {% endif %}
      </dl>
    </div>
  </section>
{% endif %}
{% endblock %}
