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

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatNullPointerException;

import java.util.ArrayList;
import java.util.List;

import org.junit.jupiter.api.Test;

/**
 * Tests für {@link CorrectionExecutionReport}.
 */
class CorrectionExecutionReportTest {

    private final CorrectionSuggestion s1 =
            new CorrectionSuggestion.CreateDirectory("/path/a", "Ordner A");
    private final CorrectionSuggestion s2 =
            new CorrectionSuggestion.CreatePromptFile("/path/prompt.txt", "Prompt erzeugen", 60);

    @Test
    void emptyReport_allAppliedIsFalse() {
        var report = new CorrectionExecutionReport(List.of());
        assertThat(report.allApplied()).isFalse();
        assertThat(report.hasFailures()).isFalse();
        assertThat(report.hasNotAttempted()).isFalse();
        assertThat(report.size()).isZero();
    }

    @Test
    void report_allApplied() {
        var report = new CorrectionExecutionReport(List.of(
                new CorrectionOutcome.Applied(s1, "ok1"),
                new CorrectionOutcome.Applied(s2, "ok2")));
        assertThat(report.allApplied()).isTrue();
        assertThat(report.hasFailures()).isFalse();
        assertThat(report.hasNotAttempted()).isFalse();
    }

    @Test
    void report_withFailure_hasFailures() {
        var report = new CorrectionExecutionReport(List.of(
                new CorrectionOutcome.Applied(s1, "ok"),
                new CorrectionOutcome.Failed(s2, "Fehler")));
        assertThat(report.hasFailures()).isTrue();
        assertThat(report.allApplied()).isFalse();
    }

    @Test
    void report_withNotAttempted_hasNotAttempted() {
        var report = new CorrectionExecutionReport(List.of(
                new CorrectionOutcome.NotAttempted(s1, "Grund")));
        assertThat(report.hasNotAttempted()).isTrue();
        assertThat(report.allApplied()).isFalse();
    }

    @Test
    void outcomesListIsImmutable() {
        var mutable = new ArrayList<CorrectionOutcome>();
        mutable.add(new CorrectionOutcome.Applied(s1, "ok"));
        var report = new CorrectionExecutionReport(mutable);
        mutable.add(new CorrectionOutcome.Failed(s2, "err"));
        assertThat(report.outcomes()).hasSize(1);
    }

    @Test
    void nullOutcomesThrows() {
        assertThatNullPointerException()
                .isThrownBy(() -> new CorrectionExecutionReport(null));
    }
}
