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

import de.gecheckt.pdf.umbenenner.domain.model.SourceDocumentLocator;

/**
 * Outbound port for copying a source PDF to the target folder.
 * <p>
 * The physical copy is the final step in the successful document processing path.
 * Copying is performed via a temporary file in the target context with a subsequent
 * atomic move/rename to the final target filename, minimising the risk of incomplete
 * target files being visible.
 *
 * <h2>Source integrity</h2>
 * <p>
 * The source file identified by the {@link SourceDocumentLocator} is <strong>never</strong>
 * modified, moved, or deleted by this port. Only a copy is written.
 *
 * <h2>No immediate retry</h2>
 * <p>
 * This port performs exactly one copy attempt per invocation. No automatic retry within
 * the same call is performed; retry decisions belong to higher-level orchestration.
 *
 * <h2>Architecture boundary</h2>
 * <p>
 * No {@code Path}, {@code File}, or NIO types appear in this interface.
 */
public interface TargetFileCopyPort {

    /**
     * Copies the source document to the target folder under the given resolved filename.
     * <p>
     * The implementation writes to a temporary file first and then performs a
     * move/rename to the final {@code resolvedFilename}. If the move fails, a
     * best-effort cleanup of the temporary file is attempted before returning the
     * failure result.
     *
     * @param sourceLocator    opaque locator identifying the source file; must not be null
     * @param resolvedFilename the final filename (not full path) to write in the target
     *                         folder; must not be null or blank; must have been obtained
     *                         from {@link TargetFolderPort#resolveUniqueFilename(String)}
     * @return {@link TargetFileCopySuccess} if the copy completed successfully, or
     *         {@link TargetFileCopyTechnicalFailure} if any step failed
     */
    TargetFileCopyResult copyToTarget(SourceDocumentLocator sourceLocator, String resolvedFilename);
}
