package de.gecheckt.pdf.umbenenner.application.validation.editor;

import java.util.List;
import java.util.Objects;

/**
 * Ergebnis einer editornahen Konfigurationsvalidierung.
 * <p>
 * Enthält alle Befunde, die der {@link EditorConfigurationValidator} aus dem aktuellen
 * Editorzustand abgeleitet hat. Das Ergebnis ist immutable.
 * <p>
 * Befunde können über {@link #findings()} als vollständige Liste abgerufen werden.
 * Feldbezogene Befunde lassen sich über {@link EditorValidationFinding#hasFieldKey()} filtern.
 *
 * @param findings  alle Validierungsbefunde; nie {@code null}
 */
public record EditorValidationReport(List<EditorValidationFinding> findings) {

    /**
     * Erstellt ein Validierungsergebnis.
     *
     * @param findings  Befundliste; darf nicht {@code null} sein
     * @throws NullPointerException wenn {@code findings} {@code null} ist
     */
    public EditorValidationReport {
        Objects.requireNonNull(findings, "findings must not be null");
        findings = List.copyOf(findings);
    }

    /**
     * Erstellt ein leeres Ergebnis ohne Befunde.
     *
     * @return ein leeres Ergebnis; nie {@code null}
     */
    public static EditorValidationReport empty() {
        return new EditorValidationReport(List.of());
    }

    /**
     * Gibt an, ob mindestens ein Befund mit Schweregrad {@link EditorValidationSeverity#ERROR} vorhanden ist.
     * <p>
     * Wenn {@code true}, gilt die Konfiguration als nicht lauffähig. Das Speichern ist jedoch
     * trotzdem erlaubt.
     *
     * @return {@code true} wenn mindestens ein Fehler-Befund vorliegt
     */
    public boolean hasErrors() {
        return findings.stream().anyMatch(f -> f.severity() == EditorValidationSeverity.ERROR);
    }

    /**
     * Gibt alle Befunde zurück, die sich auf das angegebene Feld beziehen.
     *
     * @param fieldKey  Property-Schlüssel des gesuchten Felds; darf nicht {@code null} sein
     * @return unveränderliche Liste der feldbezogenen Befunde; nie {@code null}
     */
    public List<EditorValidationFinding> findingsFor(String fieldKey) {
        Objects.requireNonNull(fieldKey, "fieldKey must not be null");
        return findings.stream()
                .filter(f -> f.fieldKey().isPresent() && f.fieldKey().get().equals(fieldKey))
                .toList();
    }
}
