package at.procon.dip.extraction.impl;

import static org.junit.jupiter.api.Assertions.*;

import at.procon.dip.classification.spi.DetectionResult;
import at.procon.dip.domain.document.ContentRole;
import at.procon.dip.domain.document.DocumentFamily;
import at.procon.dip.domain.document.DocumentType;
import at.procon.dip.extraction.spi.ExtractionRequest;
import at.procon.dip.extraction.spi.ExtractionResult;
import at.procon.dip.ingestion.spi.OriginalContentStoragePolicy;
import at.procon.dip.ingestion.spi.SourceDescriptor;
import at.procon.dip.domain.document.SourceType;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.time.OffsetDateTime;
import java.util.Map;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.junit.jupiter.api.Test;

class SpreadsheetDocumentExtractorTest {

    private final SpreadsheetDocumentExtractor extractor = new SpreadsheetDocumentExtractor();

    @Test
    void extractsOldExcelBinaryXls() throws Exception {
        byte[] data = createLegacyXls();
        SourceDescriptor source = new SourceDescriptor(
                null,
                SourceType.MAIL,
                "mail-1:attachment:report.xls",
                null,
                "report.xls",
                "application/vnd.ms-excel",
                data,
                null,
                OffsetDateTime.now(),
                OriginalContentStoragePolicy.STORE,
                Map.of("title", "report.xls")
        );
        DetectionResult detection = new DetectionResult(DocumentType.GENERIC_BINARY, DocumentFamily.GENERIC,
                "application/vnd.ms-excel", null, Map.of());

        ExtractionResult result = extractor.extract(new ExtractionRequest(source, detection, null, data));

        String text = result.derivedTextByRole().get(ContentRole.NORMALIZED_TEXT);
        assertNotNull(text);
        assertTrue(text.contains("Sheet: Sheet1"));
        assertTrue(text.contains("Name\tAmount"));
        assertTrue(text.contains("Alice\t42"));
    }

    @Test
    void extractsCsvAsNormalizedText() {
        String csv = "Name,Amount\nAlice,42\nBob,77\n";
        byte[] data = csv.getBytes(StandardCharsets.UTF_8);
        SourceDescriptor source = new SourceDescriptor(
                null,
                SourceType.FILE_SYSTEM,
                "csv-1",
                null,
                "report.csv",
                "text/csv",
                data,
                csv,
                OffsetDateTime.now(),
                OriginalContentStoragePolicy.STORE,
                Map.of("title", "report.csv")
        );
        DetectionResult detection = new DetectionResult(DocumentType.TEXT, DocumentFamily.GENERIC,
                "text/csv", null, Map.of());

        ExtractionResult result = extractor.extract(new ExtractionRequest(source, detection, csv, data));

        String text = result.derivedTextByRole().get(ContentRole.NORMALIZED_TEXT);
        assertEquals("Name,Amount\n" +
                "Alice,42\n" +
                "Bob,77", text);
    }

    private byte[] createLegacyXls() throws Exception {
        try (Workbook workbook = new HSSFWorkbook(); ByteArrayOutputStream out = new ByteArrayOutputStream()) {
            var sheet = workbook.createSheet("Sheet1");
            var header = sheet.createRow(0);
            header.createCell(0).setCellValue("Name");
            header.createCell(1).setCellValue("Amount");
            var row = sheet.createRow(1);
            row.createCell(0).setCellValue("Alice");
            row.createCell(1).setCellValue(42);
            workbook.write(out);
            return out.toByteArray();
        }
    }
}
