package org.mte.numecoeval.referentiel.steps;

import io.cucumber.java.fr.Alors;
import io.cucumber.java.fr.Et;
import io.cucumber.java.fr.Quand;
import org.apache.commons.lang3.StringUtils;
import org.mte.numecoeval.referentiel.infrastructure.restapi.dto.ImpactMessagerieDTO;
import org.mte.numecoeval.referentiel.infrastructure.restapi.controller.impactmessagerie.ReferentielImpactMessagerieRestApi;
import org.mte.numecoeval.referentiel.infrastructure.restapi.controller.impactmessagerie.ReferentielInterneImpactMessagerieRestApi;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.List;

import static io.restassured.RestAssured.given;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class ImpactMessagerieStepDefinitions extends AbstractStepDefinitions {

    List<ImpactMessagerieDTO> impactsMessageriesDisponibles;

    @Quand("le fichier CSV des impacts messageries {string} est importé par API et la réponse est {int}")
    public void importReferentielImpactMessagerie(String nomFichier, int codeReponseHttpAttendu) throws FileNotFoundException, NoSuchMethodException {
        setupRestAssured();
        File file = ResourceUtils.getFile("classpath:" + nomFichier);
        String requestPath = Arrays.stream(ReferentielInterneImpactMessagerieRestApi.class.getMethod("importCSV", MultipartFile.class)
                .getAnnotation(PostMapping.class).path()).findFirst().orElse(null);
        response = given()
                .multiPart("file", file)
                .post(requestPath)
                .thenReturn();
        assertEquals(codeReponseHttpAttendu, response.getStatusCode());
    }

    @Et("La récupération de tous les impacts de messagerie renvoie {int} lignes")
    public void getAllImpactMessagerie(int nombreLignesAttendues) throws NoSuchMethodException {
        String requestPath = Arrays.stream(ReferentielImpactMessagerieRestApi.class.getMethod("getAllImpactMessagerie")
                .getAnnotation(GetMapping.class).path()).findFirst().orElse(null);
        response = given()
                .get(requestPath)
                .thenReturn();

        assertEquals(200, response.getStatusCode());
        impactsMessageriesDisponibles = Arrays.asList(response.as(ImpactMessagerieDTO[].class));
        assertEquals(nombreLignesAttendues, impactsMessageriesDisponibles.size());
    }

    @Alors("un impact messagerie pour le critère {string} a une fonction y = {string}x + {string} et de source {string}")
    public void checkImpactMessagerieDisponible(String critere, String constanteCoefficientDirecteur, String constanteOrdonneeOrigine, String source) {

        assertTrue(
                impactsMessageriesDisponibles.stream().anyMatch(impactMessagerieDTO ->
                        StringUtils.equals(critere, impactMessagerieDTO.getCritere())
                        && Double.valueOf(constanteCoefficientDirecteur).equals(impactMessagerieDTO.getConstanteCoefficientDirecteur())
                        && Double.valueOf(constanteOrdonneeOrigine).equals(impactMessagerieDTO.getConstanteOrdonneeOrigine())
                        && StringUtils.equals(source, impactMessagerieDTO.getSource())
                )
        );

    }
}
