package org.raddatz.familienarchiv.ocr;

import org.junit.jupiter.api.Test;
import org.raddatz.familienarchiv.ocr.ScriptType;

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

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

class OcrClientDefaultStreamTest {

    @Test
    void defaultStreamBlocksSynthesizesEventsFromExtractBlocks() {
        OcrClient client = new OcrClient() {
            @Override public List<OcrBlockResult> extractBlocks(String pdfUrl, ScriptType scriptType) {
                return List.of(
                    new OcrBlockResult(0, 0.1, 0.1, 0.8, 0.04, null, "Line 1", null),
                    new OcrBlockResult(0, 0.1, 0.2, 0.8, 0.04, null, "Line 2", null),
                    new OcrBlockResult(1, 0.1, 0.1, 0.8, 0.04, null, "Line 3", null));
            }
            @Override public TrainingResult trainModel(byte[] zip) { return null; }
            @Override public TrainingResult segtrainModel(byte[] zip) { return null; }
            @Override public TrainingResult trainSenderModel(byte[] zip, String path) { return null; }
        };

        List<OcrStreamEvent> events = new ArrayList<>();
        client.streamBlocks("http://test", ScriptType.TYPEWRITER, null, events::add);

        assertThat(events).hasSize(4);
        assertThat(events.get(0)).isInstanceOf(OcrStreamEvent.Start.class);
        assertThat(((OcrStreamEvent.Start) events.get(0)).totalPages()).isEqualTo(2);

        assertThat(events.get(1)).isInstanceOf(OcrStreamEvent.Page.class);
        var page0 = (OcrStreamEvent.Page) events.get(1);
        assertThat(page0.pageNumber()).isEqualTo(0);
        assertThat(page0.blocks()).hasSize(2);

        assertThat(events.get(2)).isInstanceOf(OcrStreamEvent.Page.class);
        var page1 = (OcrStreamEvent.Page) events.get(2);
        assertThat(page1.pageNumber()).isEqualTo(1);
        assertThat(page1.blocks()).hasSize(1);

        assertThat(events.get(3)).isInstanceOf(OcrStreamEvent.Done.class);
        var done = (OcrStreamEvent.Done) events.get(3);
        assertThat(done.totalBlocks()).isEqualTo(3);
        assertThat(done.skippedPages()).isEqualTo(0);
    }

    @Test
    void defaultStreamBlocksHandlesEmptyResults() {
        OcrClient client = new OcrClient() {
            @Override public List<OcrBlockResult> extractBlocks(String pdfUrl, ScriptType scriptType) { return List.of(); }
            @Override public TrainingResult trainModel(byte[] zip) { return null; }
            @Override public TrainingResult segtrainModel(byte[] zip) { return null; }
            @Override public TrainingResult trainSenderModel(byte[] zip, String path) { return null; }
        };

        List<OcrStreamEvent> events = new ArrayList<>();
        client.streamBlocks("http://test", ScriptType.TYPEWRITER, null, events::add);

        assertThat(events).hasSize(2);
        assertThat(events.get(0)).isInstanceOf(OcrStreamEvent.Start.class);
        assertThat(((OcrStreamEvent.Start) events.get(0)).totalPages()).isEqualTo(0);
        assertThat(events.get(1)).isInstanceOf(OcrStreamEvent.Done.class);
    }
}
