package de.gecheckt.pdf.umbenenner.application.port.in;

/**
 * Inbound-Port für die manuelle Kopie der Quelldatei eines bislang nicht erfolgreich
 * verarbeiteten Dokuments mit benutzerdefiniertem Zieldateinamen.
 * <p>
 * Ermöglicht dem Benutzer, ein Dokument trotz fehlgeschlagener oder übersprungener
 * automatischer Verarbeitung manuell ins Zielverzeichnis zu überführen, ohne den
 * regulären KI-gestützten Verarbeitungspfad erneut anzustoßen. Der Use-Case führt die
 * Kopie als atomare Operation durch: Dateisystem und Persistenz werden entweder beide
 * konsistent aktualisiert oder beide bleiben im vorherigen Zustand.
 * <p>
 * <strong>Anwendungsbereich:</strong> Dokumente mit Status
 * {@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus#FAILED_RETRYABLE},
 * {@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus#FAILED_FINAL},
 * {@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus#READY_FOR_AI} oder
 * {@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus#PROPOSAL_READY}.
 * Für Dokumente mit Status
 * {@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus#SUCCESS} ist
 * stattdessen {@link ManualFileRenameUseCase} zu verwenden, da dort bereits eine
 * Zieldatei existiert.
 * <p>
 * <strong>Konfliktsemantik:</strong> Existiert im Zielordner bereits eine Datei mit dem
 * gewünschten Namen, wird anhand des Inhalts-Fingerprints entschieden:
 * <ul>
 *   <li>Gleicher Fingerprint → keine erneute Kopie ({@link ManualFileCopyNoOpIdenticalTarget}),
 *       Stammsatz wird trotzdem auf {@code SUCCESS} gehoben.</li>
 *   <li>Verschiedener Fingerprint → automatische Suffix-Vergabe ({@code (1)}, {@code (2)}, …).</li>
 * </ul>
 * <p>
 * <strong>Quellintegrität:</strong> Die Quelldatei wird nicht verändert, verschoben oder
 * gelöscht. Es entsteht ausschließlich eine Kopie im Zielordner.
 * <p>
 * <strong>Erfolg:</strong> Bei erfolgreicher Operation wechselt der Dokumentstatus auf
 * {@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus#SUCCESS}. Das Dokument
 * gilt damit fachlich als abgeschlossen und wird in zukünftigen Läufen mit
 * {@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus#SKIPPED_ALREADY_PROCESSED}
 * übersprungen.
 */
public interface ManualFileCopyUseCase {

    /**
     * Kopiert die Quelldatei eines Dokuments mit benutzerdefiniertem Zieldateinamen ins
     * Zielverzeichnis und aktualisiert den Dokument-Stammsatz auf
     * {@link de.gecheckt.pdf.umbenenner.domain.model.ProcessingStatus#SUCCESS}.
     * <p>
     * Der Aufruf ist atomar: Entweder werden Dateisystem und Persistenz beide
     * aktualisiert, oder beide bleiben unverändert. Bei einem Persistenzfehler nach
     * erfolgreicher Kopie wird die Zieldatei im Rahmen eines Best-Effort-Rollbacks
     * wieder entfernt.
     *
     * @param request die Kopieranfrage mit Fingerprint und gewünschtem Basisdateinamen;
     *                darf nicht null sein
     * @return das Ergebnis der Kopieroperation; nie null
     * @throws NullPointerException wenn {@code request} null ist
     */
    ManualFileCopyResult copy(ManualFileCopyRequest request);
}
