package com.ebay.xcelite;

import com.ebay.xcelite.exceptions.ColumnNotFoundException;
import com.ebay.xcelite.exceptions.EmptyCellException;
import com.ebay.xcelite.model.CamelCase;
import com.ebay.xcelite.model.UsStringCellDateConverter;
import com.ebay.xcelite.options.XceliteOptions;
import com.ebay.xcelite.policies.MissingCellPolicy;
import com.ebay.xcelite.reader.BeanSheetReader;
import com.ebay.xcelite.reader.SheetReader;
import com.ebay.xcelite.sheet.XceliteSheet;
import lombok.SneakyThrows;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;

public class BeanReaderTests extends AbstractTestBaseForWriterTests {
    private SimpleDateFormat df = new SimpleDateFormat(UsStringCellDateConverter.DATE_PATTERN);

    private static String usTestData[][] = {
            {"Crystal",	"Maiden",	"01/02/1990",	"female"},
            {"Witch",	"Doctor",	"01/01/1990",	"male"}
    };

    @BeforeAll
    @SneakyThrows
    static void setup() {
    }

    @Test
    @DisplayName("Must correctly read a header row where some columns are not mapped to annotated properties")
    void mustReadHeaderRowWithMissingCellsOK() {
        XceliteOptions options = new XceliteOptions();
        options.setSkipRowsBeforeColumnDefinitionRow(3);

        List<CamelCase> upper = getData(options, "src/test/resources/ColumnDefinitionRowHasEmptyCells.xlsx");
        validateData(upper);
    }

    @Test
    @DisplayName("Must correctly throw reading a header row where some columns are not mapped to annotated properties")
    public void mustThrowReadingHeaderRowWithMissingCellsOK() {
        XceliteOptions options = new XceliteOptions();
        options.setSkipRowsBeforeColumnDefinitionRow(3);
        options.setMissingCellPolicy(MissingCellPolicy.THROW);

        assertThrows(EmptyCellException.class, () -> {
            List<CamelCase> upper = getData(options, "src/test/resources/ColumnDefinitionRowHasEmptyCells.xlsx");
            validateData(upper);
        });
    }

    @SneakyThrows
    private List<CamelCase> getData(XceliteOptions options, String filePath)  {
        Xcelite xcelite = new Xcelite(new File(filePath));
        XceliteSheet sheet = xcelite.getSheet(0);
        SheetReader<CamelCase> beanReader = new BeanSheetReader<>(sheet, options, CamelCase.class);
        ArrayList<CamelCase> data = new ArrayList<>(beanReader.read());
        return data;
    }

    @SneakyThrows
    private void validateData(List<CamelCase> data) {
        CamelCase first = data.get(0);
        assertEquals(usTestData[0][0], first.getName(), "Name mismatch");
        assertEquals(usTestData[0][1], first.getSurname(), "Surname mismatch");
        assertEquals(df.parse(usTestData[0][2]), first.getBirthDate(), "Birthdate mismatch");

        CamelCase second = data.get(1);
        assertEquals(usTestData[1][0], second.getName(), "Name mismatch");
        assertEquals(usTestData[1][1], second.getSurname(), "Surname mismatch");
        assertEquals(df.parse(usTestData[1][2]), second.getBirthDate(), "Birthdate mismatch");
    }
}

@@ -24,68 +24,8 @@
 e;%0A%0A
-import com.ebay.xcelite.exceptions.ColumnNotFoundException;%0A
 impo
@@ -441,49 +441,8 @@
 ws;%0A
-import org.junit.jupiter.api.Assertions;%0A
 impo
@@ -580,41 +580,8 @@
 le;%0A
-import java.text.ParseException;%0A
 impo
@@ -665,30 +665,8 @@
 ist;
-%0Aimport java.util.Map;
 %0A%0Aim
@@ -1128,97 +1128,1121 @@
    @
-BeforeAll%0A    @SneakyThrows%0A    static void setup() %7B%0A    %7D%0A%0A    @Test%0A    @DisplayName(%22
+Test%0A    @DisplayName(%22MissingCellPolicy default - Must correctly read a header row where some columns are not mapped to annotated properties%22)%0A    void mustReadHeaderRowWithMissingCellsOK() %7B%0A        XceliteOptions options = new XceliteOptions();%0A        options.setSkipRowsBeforeColumnDefinitionRow(3);%0A%0A        List%3CCamelCase%3E upper = getData(options, %22src/test/resources/ColumnDefinitionRowHasEmptyCells.xlsx%22);%0A        validateData(upper);%0A    %7D%0A%0A    @Test%0A    @DisplayName(%22MissingCellPolicy.RETURN_BLANK_AS_NULL - Must correctly read a header row where some columns are not mapped to annotated properties%22)%0A    void mustReadHeaderRowWithMissingCellsWithMissingCellPolicy_RETURN_BLANK_AS_NULL_OK() %7B%0A        XceliteOptions options = new XceliteOptions();%0A        options.setSkipRowsBeforeColumnDefinitionRow(3);%0A        options.setMissingCellPolicy(MissingCellPolicy.RETURN_BLANK_AS_NULL);%0A%0A        List%3CCamelCase%3E upper = getData(options, %22src/test/resources/ColumnDefinitionRowHasEmptyCells.xlsx%22);%0A        validateData(upper);%0A    %7D%0A%0A    @Test%0A    @DisplayName(%22MissingCellPolicy.RETURN_NULL_AND_BLANK - 
 Must
@@ -2364,32 +2364,76 @@
 WithMissingCells
+WithMissingCellPolicy_RETURN_NULL_AND_BLANK_
 OK() %7B%0A        X
@@ -2526,32 +2526,111 @@
 efinitionRow(3);
+%0A        options.setMissingCellPolicy(MissingCellPolicy.RETURN_NULL_AND_BLANK);
 %0A%0A        List%3CC
@@ -2789,16 +2789,42 @@
 ayName(%22
+MissingCellPolicy.THROW - 
 Must cor

Test for issues with empty header columns