# XML-Hash-Duplikatserkennung und intelligente Dateinamen-Verwaltung

## Übersicht

Diese Dokumentation beschreibt die erweiterte Funktionalität zur Hash-basierten Duplikatserkennung von XML-Dateien und intelligenten Dateinamen-Verwaltung in der XSL-Validator-Anwendung.

## Neue Funktionalitäten

### 1. Hash-basierte Duplikatserkennung

Beim Hinzufügen neuer XML-Dateien wird automatisch geprüft, ob bereits eine Datei mit identischem Inhalt (basierend auf blake2b-Hash) im Projekt vorhanden ist.

**Vorteile:**
- Vermeidung von Datei-Duplikaten
- Automatische Zuordnung vorhandener Dateien
- Speicherplatz-Optimierung
- Konsistente Datenintegrität

### 2. Intelligente Dateinamen-Verwaltung

Bei Dateinamen-Konflikten werden automatisch alternative Namen im Format `datei_1.xml`, `datei_2.xml`, etc. generiert.

**Features:**
- Automatische Generierung alternativer Dateinamen
- Benutzerfreundlicher Auswahl-Dialog
- Vermeidung von Überschreibungen
- Konsistente Namenskonventionen

### 3. Nahtlose Integration

Die neuen Funktionalitäten sind vollständig in bestehende Workflows integriert:
- **Drag & Drop**: Automatische Hash-Prüfung beim Ziehen von XML-Dateien
- **Kontextmenü**: Hash-Prüfung beim manuellen Hinzufügen über "XML-Datei hinzufügen"

## Technische Implementierung

### Kern-Architektur

```python
def _assign_xml_to_xsl_nodes(self, xml_file_path: Path, selected_xsl_nodes: list):
    # 1. Hash berechnen
    file_hash = self._calculate_hash_for_file(xml_file_path)
    
    # 2. Duplikatsprüfung
    existing_xml = self._find_xml_file_by_hash(file_hash)
    
    if existing_xml:
        # 3. Automatische Zuordnung bei Hash-Match
        self._assign_existing_xml_to_nodes(existing_xml, selected_xsl_nodes)
    else:
        # 4. Neue Datei verarbeiten
        self._process_new_xml_file(xml_file_path, selected_xsl_nodes, file_hash)
```

### Neue Hilfsmethoden

#### Hash-Vergleich und Suche

```python
def _get_all_project_xml_files(self) -> List[XmlFile]:
    """Sammelt alle XML-Dateien aus dem gesamten Projekt."""

def _find_xml_file_by_hash(self, target_hash: str) -> XmlFile | None:
    """Sucht XML-Datei mit spezifischem Hash im Projekt."""

def _calculate_hash_for_file(self, file_path: Path) -> str | None:
    """Berechnet blake2b-Hash für eine Datei."""
```

#### Dateinamen-Verwaltung

```python
def _generate_alternative_filename(self, original_path: Path, xml_dir: Path) -> Path:
    """Generiert alternative Dateinamen im Format: datei_1.xml, datei_2.xml, ..."""

def _is_filename_used_in_project(self, relative_xml_path: Path) -> bool:
    """Prüft ob Dateiname bereits im Projekt verwendet wird."""

def _show_filename_selection_dialog(self, original_name: str, alternative_paths: List[Path]) -> Path | None:
    """Zeigt Dialog zur Auswahl alternativer Dateinamen."""
```

#### Verarbeitungslogik

```python
def _assign_existing_xml_to_nodes(self, existing_xml: XmlFile, selected_xsl_nodes: list):
    """Ordnet vorhandene XML-Datei (Hash-Match) den XSL-Knoten zu."""

def _process_new_xml_file(self, xml_file_path: Path, selected_xsl_nodes: list, file_hash: str | None):
    """Verarbeitet neue XML-Datei (kein Hash-Match)."""
```

## Benutzer-Workflows

### Workflow 1: Hash-Duplikat gefunden

1. Benutzer fügt XML-Datei hinzu (Drag&Drop oder Kontextmenü)
2. System berechnet Hash der neuen Datei
3. Hash-Match mit vorhandener Datei gefunden
4. **Automatische Zuordnung**: Vorhandene Datei wird den ausgewählten XSL-Knoten zugeordnet
5. Erfolgsmeldung: "XML-Datei mit gleichem Inhalt bereits vorhanden - automatisch zugeordnet"

### Workflow 2: Neue Datei, Dateiname-Konflikt

1. Benutzer fügt XML-Datei hinzu
2. Kein Hash-Match gefunden (neue Datei)
3. Dateiname bereits vorhanden
4. **Dialog angezeigt**: Auswahl alternativer Dateinamen
5. Benutzer wählt gewünschten Namen
6. Datei wird kopiert und zugeordnet
7. Erfolgsmeldung mit Hinweis auf Umbenennung

### Workflow 3: Neue Datei, kein Konflikt

1. Benutzer fügt XML-Datei hinzu
2. Kein Hash-Match gefunden
3. Dateiname verfügbar
4. **Direkte Verarbeitung**: Datei wird kopiert und zugeordnet
5. Standard-Erfolgsmeldung

## Benutzeroberfläche

### Hash-Duplikat Dialog

```
┌─────────────────────────────────────────┐
│ XML-Datei zugeordnet                    │
├─────────────────────────────────────────┤
│ Eine XML-Datei mit gleichem Inhalt war  │
│ bereits im Projekt vorhanden.           │
│                                         │
│ Die vorhandene Datei 'dokument.xml'     │
│ wurde automatisch zu 2 XSL-Knoten      │
│ zugeordnet.                             │
├─────────────────────────────────────────┤
│                    [OK]                 │
└─────────────────────────────────────────┘
```

### Dateiname-Auswahl Dialog

```
┌─────────────────────────────────────────┐
│ Dateiname auswählen                     │
├─────────────────────────────────────────┤
│ Eine Datei mit dem Namen 'test.xml'     │
│ existiert bereits.                      │
│                                         │
│ Bitte wählen Sie einen alternativen     │
│ Dateinamen:                             │
│                                         │
│ ○ test_1.xml                           │
│ ● test_2.xml                           │
│ ○ test_3.xml                           │
│ ○ test_4.xml                           │
├─────────────────────────────────────────┤
│              [OK] [Abbrechen]           │
└─────────────────────────────────────────┘
```

## Performance-Optimierungen

### Hash-Berechnung
- **Synchrone Berechnung** für neue Dateien (akzeptable Verzögerung)
- **Effiziente blake2b-Implementierung** aus Python's hashlib
- **Caching** von Hash-Werten in XmlFile-Objekten

### Projekt-weite Suche
- **Einmalige Sammlung** aller XML-Dateien pro Operation
- **Optimierte Rekursion** durch die Node-Struktur
- **Duplikat-Vermeidung** bei der Sammlung

### Dateinamen-Generierung
- **Sequenzielle Suche** mit Sicherheitsgrenze (max. 1000 Versuche)
- **Fallback-Mechanismus** mit Zeitstempel
- **Kombinierte Prüfung** von physischer Existenz und Projekt-Verwendung

## Fehlerbehandlung

### Hash-Berechnung Fehler
```python
try:
    file_hash = self._calculate_hash_for_file(xml_file_path)
except Exception as e:
    logger.error(f"Hash-Berechnung fehlgeschlagen: {e}")
    # Fortsetzung ohne Hash (Fallback-Verhalten)
```

### Datei-Zugriff Fehler
```python
if not file_path.exists():
    logger.warning(f"Datei nicht gefunden: {file_path}")
    return None
```

### Dialog-Fehler
```python
try:
    selected_path = self._show_filename_selection_dialog(...)
except Exception as e:
    logger.error(f"Dialog-Fehler: {e}")
    # Fallback: Ersten alternativen Namen verwenden
    return alternative_paths[0] if alternative_paths else None
```

## Logging

Das System verwendet strukturiertes Logging für alle Operationen:

```python
logger.info(f"Hash-Duplikat gefunden: {existing_xml.xml} hat gleichen Hash wie {xml_file_path.name}")
logger.debug(f"Hash-Vergleich: {len(xml_files)} XML-Dateien im Projekt gefunden")
logger.warning(f"Hash-Berechnung für {xml_file_path} fehlgeschlagen")
logger.error(f"Fehler beim Zuordnen der XML-Datei: {str(e)}")
```

## Testing

### Umfassende Test-Suite

Die Implementierung wird durch eine umfassende Test-Suite validiert:

```bash
uv run python test_xml_hash_duplicate_detection.py
```

**Test-Abdeckung:**
- Hash-Berechnung und -Konsistenz
- XmlFile-Modell mit Hash-Unterstützung
- Duplikatserkennung-Logik
- Alternative Dateinamen-Generierung
- Integration Workflow

### Test-Ergebnisse

```
=== Test: Hash-Berechnung ===
[OK] Hash-Berechnung funktioniert korrekt

=== Test: XmlFile-Modell mit Hash ===
[OK] XmlFile-Modell mit Hash funktioniert korrekt

=== Test: Duplikatserkennung-Logik ===
[OK] Duplikatserkennung-Logik funktioniert korrekt

=== Test: Alternative Dateinamen-Generierung ===
[OK] Alternative Dateinamen-Generierung funktioniert korrekt

=== Test: Integration Workflow ===
[OK] Integration Workflow funktioniert korrekt

[SUCCESS] Alle Tests erfolgreich abgeschlossen!
```

## Kompatibilität

### Rückwärtskompatibilität
- **Bestehende Projekte** funktionieren unverändert
- **Vorhandene XML-Dateien** ohne Hash werden automatisch nachberechnet
- **Keine Breaking Changes** in der API

### Datenformat
- **XmlFile.hashsum** ist optional (kann None sein)
- **Automatische Migration** beim Projektladen
- **Graceful Degradation** bei Hash-Fehlern

## Wartung und Erweiterung

### Konfigurierbarkeit
Die Implementierung kann einfach erweitert werden:

```python
# Verschiedene Hash-Algorithmen
def _calculate_hash(self, file_path: Path, algorithm: str = "blake2b"):
    if algorithm == "blake2b":
        return self._calculate_blake2b_hash(file_path)
    elif algorithm == "sha256":
        return self._calculate_sha256_hash(file_path)

# Konfigurierbare Dateinamen-Formate
def _generate_alternative_filename(self, original_path: Path, format_pattern: str = "{name}_{counter}{ext}"):
    # Implementierung mit konfigurierbaren Mustern
```

### Monitoring
```python
# Performance-Metriken
start_time = time.time()
# ... Operation ...
duration = time.time() - start_time
logger.info(f"Hash-Vergleich abgeschlossen in {duration:.3f}s")
```

## Changelog

### Version 1.0.0 (2025-01-20)
- ✅ Hash-basierte Duplikatserkennung im gesamten Projekt
- ✅ Automatische Zuordnung bei Hash-Match
- ✅ Intelligente Dateinamen-Generierung (datei_1.xml Format)
- ✅ Integration in Drag&Drop und Kontextmenü
- ✅ Benutzerfreundliche Dateiname-Auswahl-Dialoge
- ✅ Umfassende Test-Suite
- ✅ Strukturiertes Logging
- ✅ Fehlerbehandlung und Fallback-Mechanismen

## Fazit

Die erweiterte XML-Hash-Duplikatserkennung bietet eine robuste, benutzerfreundliche Lösung für die intelligente Verwaltung von XML-Dateien in XSL-Validator-Projekten. Die Implementierung ist vollständig getestet, performant und nahtlos in bestehende Workflows integriert.