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

/**
 * Inbound-Port zur Steuerung des automatischen Schedulers.
 * <p>
 * Dieser Use Case kapselt den vollständigen Scheduler-Lifecycle:
 * Starten, Stoppen und Abfragen des aktuellen Zustands. Die Steuerung
 * erfolgt ausschließlich über dieses Interface – GUI-Komponenten kennen
 * weder den {@code SchedulerPort} noch Bootstrap-interne Typen.
 * <p>
 * Alle Operationen sind idempotent: Ein {@link #start()} auf einem
 * bereits laufenden Scheduler ist ein No-op; ein {@link #stop()} auf
 * einem bereits gestoppten Scheduler ebenso.
 * <p>
 * Implementierungen verwalten den Zustand threadsicher über eine
 * {@code AtomicReference<SchedulerStatus>}.
 */
public interface SchedulerControlUseCase {

    /**
     * Startet den automatischen Scheduler.
     * <p>
     * Ist der Scheduler bereits aktiv ({@code state != STOPPED}), hat
     * dieser Aufruf keine Wirkung. Andernfalls wird der Scheduler über
     * folgende Sequenz gestartet:
     * <ol>
     *   <li>Zustand auf {@code STARTING} setzen</li>
     *   <li>Exklusiven OS-Lock auf Konfigurationsdatei erwerben</li>
     *   <li>Scheduler-Adapter starten (erster Tick sofort)</li>
     *   <li>Zustand auf {@code RUNNING_IDLE} setzen</li>
     * </ol>
     * Schlägt ein Schritt fehl, wird ein vollständiger Rollback
     * durchgeführt und der Zustand auf {@code STOPPED} zurückgesetzt.
     *
     * @throws SchedulerStartException wenn der Start fehlschlägt und
     *         kein Rollback möglich ist; enthält eine deutsche Meldung
     *         für die GUI-Anzeige
     */
    void start() throws SchedulerStartException;

    /**
     * Stoppt den automatischen Scheduler.
     * <p>
     * Ist der Scheduler bereits gestoppt, hat dieser Aufruf keine Wirkung.
     * Läuft gerade ein Tick, wechselt der Zustand zu
     * {@code STOPPING_BATCH_ACTIVE}; der laufende Batch wird regulär
     * zu Ende geführt. Danach wird der OS-Lock freigegeben.
     */
    void stop();

    /**
     * Gibt den aktuellen Scheduler-Zustand als unveränderlichen Snapshot zurück.
     * <p>
     * Der Snapshot kann von beliebigen Threads gelesen werden. Die GUI
     * ruft diese Methode regelmäßig über eine zentrale Status-Refresh-Timeline
     * auf und aktualisiert alle betroffenen Tabs entsprechend.
     *
     * @return aktueller Scheduler-Status; nie {@code null}
     */
    SchedulerStatus getStatus();

    /**
     * Gibt das aktuell konfigurierte Ausführungsintervall in Sekunden zurück.
     * <p>
     * Wird vom Scheduler-Tab genutzt, um den Initialwert des Intervall-Feldes
     * anzuzeigen. Der Wert entspricht dem beim Start der Anwendung geladenen
     * Konfigurationswert (mindestens 30 Sekunden).
     *
     * @return Intervall in Sekunden; immer &ge; 30
     */
    int getIntervalSeconds();

    /**
     * Persistiert das Ausführungsintervall in die Konfigurationsdatei.
     * <p>
     * Sicher nur aufzurufen wenn der Scheduler gestoppt ist. Der in-Memory-Wert
     * wird nicht aktualisiert; der neue Wert wird beim nächsten Anwendungsstart
     * gelesen.
     * <p>
     * Muss auf einem Hintergrund-Thread aufgerufen werden, da der Schreibvorgang
     * den Konfigurations-Datei-Lock erwerben muss.
     *
     * @param seconds Intervall in Sekunden; sollte &ge; 30 sein
     */
    void saveIntervalSeconds(int seconds);
}
