"""Generator für die Fabric Environment-Dokumentation.

Analog zu :mod:`core.lakehouse_doc_generator`: eingebaute Standard-Vorlage +
Rendering aus einem :class:`~core.models.EnvironmentInfo`. Environments
(Spark-Environments) sind property-basierte Items; die Doku basiert auf den
Item-Properties, den installierten Bibliotheken sowie den Spark-Compute-/
Runtime-Einstellungen (best-effort über separate Endpunkte gelesen).
"""
from __future__ import annotations

from core.models import EnvironmentInfo, EnvironmentLibraryInfo
from core.template_renderer import TemplateRenderer
from core.workspace_doc_generator import _escape_cell, ensure_template, load_template

ENVIRONMENT_TEMPLATE_FILENAME = "WorkspaceEnvironmentvorlage.md"

__all__ = [
    "ENVIRONMENT_TEMPLATE_FILENAME",
    "DEFAULT_ENVIRONMENT_TEMPLATE",
    "ensure_template",
    "load_template",
    "build_libraries_table",
    "build_compute_section",
    "build_service_hint",
    "build_environment_values",
    "render_environment",
]


DEFAULT_ENVIRONMENT_TEMPLATE = """# Microsoft Fabric Environment-Dokumentation

> **Hinweis:** Diese Dokumentation ist verpflichtend für alle Produktiv-Environments.
> Nicht relevante Kapitel können leer bleiben, dürfen jedoch nicht entfernt werden.
> Automatisch befüllte Felder stammen aus dem Microsoft Fabric Service; mit
> _„Manuell zu ergänzen"_ markierte Felder sind fachlich zu vervollständigen.

---

## 1. Metadaten

| Feld | Wert |
|-----|------|
| Environment-Name | {{ENV_Name}} |
| Beschreibung | {{ENV_Beschreibung}} |
| Environment-ID | {{ENV_ID}} |
| Web-URL | {{ENV_WebUrl}} |
| Spark-Runtime-Version | {{ENV_RuntimeVersion}} |
| Anzahl Bibliotheken | {{ENV_AnzahlBibliotheken}} |
| Erstellt / konfiguriert von | {{ENV_ConfiguredBy}} |
| Zuletzt geändert | {{ENV_ModifiedTime}} |
| Fachbereich | {{ENV_Fachbereich}} |
| Konzerndomäne | {{ENV_Konzerndomaene}} |
| Aktuelle Version | 1.0 |
| Status | Produktiv |
| Letzte Aktualisierung | {{ENV_ExportDatum}} |

---

## 2. Ansprechpartner & Verantwortlichkeiten

| Rolle | Name / Team | Kontakt |
|-----|-------------|--------|
| Fachlicher Owner | {{KONTAKT_BusinessOwner}} | {{KONTAKT_BusinessOwnerMail}} |
| Technischer Owner | {{KONTAKT_TechOwner}} | {{KONTAKT_TechOwnerMail}} |
| Data Steward | {{KONTAKT_DataSteward}} | {{KONTAKT_DataStewardMail}} |
| Betrieb / Support | {{KONTAKT_Betrieb}} | {{KONTAKT_BetriebMail}} |

---

## 3. Business-Ziel & fachlicher Kontext

### 3.1 Zielsetzung
{{ENV_Zielsetzung}}

### 3.2 Fachlicher Anwendungsfall
{{ENV_Anwendungsfall}}

### 3.3 Nachgelagerte Verbraucher (Notebooks / Spark Job Definitions)
{{ENV_Konsumenten}}

---

## 4. Aufbau & Konfiguration

### 4.1 Installierte Bibliotheken

{{ENV_BibliothekenTabelle}}

### 4.2 Spark-Compute & Runtime

{{ENV_ComputeTabelle}}

---

## 5. Datenquellen & Abhängigkeiten

### 5.1 Abhängigkeiten / vorgelagerte Prozesse

{{ENV_DatenquellenTabelle}}

### 5.2 Detailbeschreibung je Abhängigkeit
{{ENV_DatenquellenDetail}}

---

## 6. Inhalt & Nutzung

{{ENV_ServiceHinweis}}

### 6.1 Verwendung in Notebooks / Spark Jobs
{{ENV_VerwendungHinweis}}

### 6.2 Parameter & Konfiguration
{{ENV_ParameterHinweis}}

### 6.3 Datenqualität

- Umgang mit Abhängigkeitskonflikten: {{ENV_NullHandling}}
- Validierung der Bibliotheksversionen: {{ENV_Validierungsregeln}}
- Aufbewahrung / Versionierung: {{ENV_Aufbewahrung}}

### 6.4 Performance-Hinweise

- Compute-Optimierung / Pool-Wahl: {{ENV_Optimierung}}
- Bekannte Performance-Engpässe: {{ENV_PerformanceHinweise}}
- Weitere Maßnahmen: {{ENV_Optimierungen}}

---

## 7. Betrieb & Wartung

### 7.1 Veröffentlichung & Orchestrierung

{{ENV_Beladung}}

### 7.2 Monitoring & Fehlerbehandlung
{{ENV_Monitoring}}

### 7.3 Bekannte Probleme / Technische Schulden
{{ENV_BekannteProbleme}}

---

## 8. Sicherheit & Berechtigungen

### 8.1 Zugriff & Freigaben
{{ENV_Zugriffe}}

### 8.2 Sensitivity Labels
{{ENV_Labels}}

### 8.3 Risiken & Einschränkungen
{{ENV_Risiken}}

---

## 9. Versionierung & Änderungsverlauf

### 9.1 Repository / Ablage
{{ENV_Repository}}

### 9.2 Änderungsprotokoll

| Version | Datum | Änderung | Typ (fachlich/technisch) | Autor |
|-------|-------|---------|--------------------------|-------|
| 1.0 | {{ENV_ExportDatum}} | Automatische Erst-Dokumentation | technisch | Auto-Dokumentation |

---

## 10. Freigabe & Review

| Rolle | Name | Datum | Kommentar |
|-----|------|-------|----------|
| Fachlich | {{REVIEW_FachName}} | {{REVIEW_FachDatum}} | {{REVIEW_FachKommentar}} |
| Technisch | {{REVIEW_TechName}} | {{REVIEW_TechDatum}} | {{REVIEW_TechKommentar}} |

---

## 11. Anhänge & Referenzen
- Übergeordnete Workspace-Dokumentation
- Architekturdiagramme
- Regulatorische Nachweise (separat)
"""


def _t(language: str, de: str, en: str) -> str:
    return en if (language or "de").lower().startswith("en") else de


def _manual_hint(language: str) -> str:
    return _t(language, "_Manuell zu ergänzen_", "_To be completed_")


def _none(language: str) -> str:
    return _t(language, "–", "–")


def build_libraries_table(
    libraries: list[EnvironmentLibraryInfo], language: str = "de"
) -> str:
    """Baut die Tabelle der installierten Bibliotheken."""
    if not libraries:
        return _t(
            language,
            "_Keine Bibliotheken verfügbar._",
            "_No libraries available._",
        )
    header = _t(
        language,
        "| Bibliothek | Typ | Version |",
        "| Library | Type | Version |",
    )
    dash = _none(language)
    lines = [header, "|---|---|---|"]
    for lib in libraries:
        lines.append(
            f"| {_escape_cell(lib.name)} | "
            f"{_escape_cell(lib.library_type) or dash} | "
            f"{_escape_cell(lib.version) or dash} |"
        )
    return "\n".join(lines)


def build_compute_section(env: EnvironmentInfo, language: str = "de") -> str:
    """Baut die Tabelle mit Spark-Compute-/Runtime-Einstellungen."""
    dash = _none(language)
    header = _t(language, "| Eigenschaft | Wert |", "| Property | Value |")
    runtime_lbl = _t(language, "Runtime-Version", "Runtime version")
    pool_lbl = _t(language, "Instanz-Pool", "Instance pool")
    pool_type_lbl = _t(language, "Pool-Typ", "Pool type")
    driver_lbl = _t(language, "Driver (Cores / Memory)", "Driver (cores / memory)")
    exec_lbl = _t(language, "Executor (Cores / Memory)", "Executor (cores / memory)")
    dyn_lbl = _t(language, "Dynamische Executor-Allokation", "Dynamic executor allocation")
    driver = "/".join(x for x in (env.driver_cores, env.driver_memory) if x) or dash
    executor = "/".join(x for x in (env.executor_cores, env.executor_memory) if x) or dash
    lines = [
        header,
        "|---|---|",
        f"| {runtime_lbl} | {_escape_cell(env.runtime_version) or dash} |",
        f"| {pool_lbl} | {_escape_cell(env.instance_pool_name) or dash} |",
        f"| {pool_type_lbl} | {_escape_cell(env.instance_pool_type) or dash} |",
        f"| {driver_lbl} | {_escape_cell(driver)} |",
        f"| {exec_lbl} | {_escape_cell(executor)} |",
        f"| {dyn_lbl} | {_escape_cell(env.dynamic_allocation) or dash} |",
    ]
    return "\n".join(lines)


def build_service_hint(language: str = "de") -> str:
    return _t(
        language,
        "> **Hinweis:** Die Metadaten stammen aus den Environment-Properties, "
        "der Bibliotheksliste und den Spark-Compute-Einstellungen des Microsoft "
        "Fabric Service. Fachliche Beschreibungen sind manuell zu ergänzen.",
        "> **Note:** The metadata comes from the environment properties, the "
        "library list and the Spark compute settings of the Microsoft Fabric "
        "service. Business descriptions must be completed manually.",
    )


_MANUAL_PLACEHOLDERS = (
    "KONTAKT_BusinessOwner",
    "KONTAKT_BusinessOwnerMail",
    "KONTAKT_TechOwner",
    "KONTAKT_TechOwnerMail",
    "KONTAKT_DataSteward",
    "KONTAKT_DataStewardMail",
    "KONTAKT_Betrieb",
    "KONTAKT_BetriebMail",
    "ENV_Fachbereich",
    "ENV_Konzerndomaene",
    "ENV_Zielsetzung",
    "ENV_Anwendungsfall",
    "ENV_Konsumenten",
    "ENV_DatenquellenDetail",
    "ENV_ParameterHinweis",
    "ENV_NullHandling",
    "ENV_Validierungsregeln",
    "ENV_Aufbewahrung",
    "ENV_Optimierung",
    "ENV_PerformanceHinweise",
    "ENV_Optimierungen",
    "ENV_Monitoring",
    "ENV_BekannteProbleme",
    "ENV_Zugriffe",
    "ENV_Labels",
    "ENV_Risiken",
    "ENV_Repository",
    "REVIEW_FachName",
    "REVIEW_FachDatum",
    "REVIEW_FachKommentar",
    "REVIEW_TechName",
    "REVIEW_TechDatum",
    "REVIEW_TechKommentar",
)


def build_environment_values(
    env: EnvironmentInfo, export_date: str, language: str = "de"
) -> dict[str, str]:
    """Baut das Platzhalter-Wörterbuch für die Environment-Vorlage."""
    hint = _manual_hint(language)
    dash = _none(language)

    values: dict[str, str] = {name: hint for name in _MANUAL_PLACEHOLDERS}
    values.update(
        {
            "ENV_Name": env.name or dash,
            "ENV_Beschreibung": env.description or dash,
            "ENV_ID": env.id or dash,
            "ENV_WebUrl": env.web_url or dash,
            "ENV_RuntimeVersion": env.runtime_version or dash,
            "ENV_AnzahlBibliotheken": str(len(env.libraries)),
            "ENV_ConfiguredBy": env.configured_by or dash,
            "ENV_ModifiedTime": env.modified_time or dash,
            "ENV_ExportDatum": export_date,
            "ENV_BibliothekenTabelle": build_libraries_table(env.libraries, language),
            "ENV_ComputeTabelle": build_compute_section(env, language),
            "ENV_ServiceHinweis": build_service_hint(language),
            "ENV_DatenquellenTabelle": _t(
                language,
                "_Abhängigkeiten (Notebooks, Spark Jobs) werden nicht automatisch "
                "ermittelt. Bitte fachlich ergänzen._",
                "_Dependencies (notebooks, Spark jobs) are not determined "
                "automatically. Please complete manually._",
            ),
            "ENV_VerwendungHinweis": _t(
                language,
                "_Environments werden von Notebooks und Spark Job Definitions als "
                "Ausführungsumgebung referenziert. Bitte konkrete Verwendung "
                "fachlich ergänzen._",
                "_Environments are referenced by notebooks and Spark job "
                "definitions as their execution environment. Please complete the "
                "concrete usage manually._",
            ),
            "ENV_Beladung": _t(
                language,
                "_Änderungen an Bibliotheken/Compute werden über die "
                "Veröffentlichung (Publish) des Environments aktiv. Bitte "
                "Veröffentlichungsprozess fachlich ergänzen._",
                "_Changes to libraries/compute take effect after publishing the "
                "environment. Please complete the publishing process manually._",
            ),
        }
    )
    return values


def render_environment(
    template_content: str,
    env: EnvironmentInfo,
    export_date: str,
    language: str = "de",
) -> str:
    """Rendert ein eigenständiges Environment-Dokument anhand der Vorlage."""
    values = build_environment_values(env, export_date, language)
    rendered, _warnings = TemplateRenderer().render(template_content, values)
    return rendered
