package org.mte.numecoeval.referentiel.domain.port.input;

import org.apache.commons.csv.CSVRecord;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mte.numecoeval.referentiel.domain.exception.ReferentielException;
import org.mte.numecoeval.referentiel.domain.ports.input.ImportCSVReferentielPort;
import org.mte.numecoeval.referentiel.domain.ports.input.impl.ImportCorrespondanceRefEquipementPortImpl;
import org.mte.numecoeval.referentiel.infrastructure.restapi.dto.CorrespondanceRefEquipementDTO;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
class ImportCSVReferentielPortTest {

    @Mock
    CSVRecord csvRecord;

    ImportCSVReferentielPort<CorrespondanceRefEquipementDTO> importPortToTest = new ImportCorrespondanceRefEquipementPortImpl();

    @Test
    void checkFieldIsMappedInCSVRecord_whenFieldIsntMapped_shouldThrowException() {
        var field = "test";
        when(csvRecord.getRecordNumber()).thenReturn(0L);
        when(csvRecord.isMapped(field)).thenReturn(false);

        var exception = assertThrows(ReferentielException.class, () -> importPortToTest.checkFieldIsMappedInCSVRecord(csvRecord, field));
        assertEquals("La ligne n°1 est invalide : La colonne test doit être présente", exception.getMessage());
    }

    @Test
    void getStringValueFromRecord_shouldUseAlternativeNamesIfFieldUnavailable() {
        var field = "test";
        var alternativeName = "alternativeField";
        when(csvRecord.isMapped(field)).thenReturn(false);
        when(csvRecord.isMapped(alternativeName)).thenReturn(true);
        String expectedValue = "Value";
        when(csvRecord.get(alternativeName)).thenReturn(expectedValue);

        var result = importPortToTest.getStringValueFromRecord(csvRecord, field, alternativeName);
        assertEquals(expectedValue, result);
    }
}
