package org.mte.numecoeval.calculs.infrastructure.controller;

import lombok.extern.slf4j.Slf4j;
import org.mte.numecoeval.calculs.domain.exception.CalculImpactException;
import org.mte.numecoeval.calculs.domain.exception.CalculImpactRuntimeException;
import org.mte.numecoeval.calculs.rest.generated.api.model.ErreurRest;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.context.request.WebRequest;

import java.time.LocalDateTime;

import static org.springframework.http.HttpStatus.BAD_REQUEST;
import static org.springframework.http.HttpStatus.INTERNAL_SERVER_ERROR;

@Slf4j
@RestControllerAdvice
public class ExceptionHandler {

    /**
     * writer error message
     *
     * @param ex     excepetion
     * @param status le statut http
     * @return l'objet erreur
     */
    private static ErreurRest writeErrorResponse(Exception ex, HttpStatus status) {
        var erreurRest = new ErreurRest();
        erreurRest.status(status.value());
        erreurRest.setCode(status.name());
        erreurRest.setTimestamp(LocalDateTime.now());
        erreurRest.setMessage(ex.getLocalizedMessage());
        return erreurRest;
    }

    @org.springframework.web.bind.annotation.ExceptionHandler(value = {CalculImpactException.class})
    @ResponseStatus(value = BAD_REQUEST)
    public ErreurRest calculImpactException(Exception ex, WebRequest request) {
        return writeErrorResponse(ex, BAD_REQUEST);
    }

    @org.springframework.web.bind.annotation.ExceptionHandler(value = {CalculImpactRuntimeException.class})
    @ResponseStatus(value = INTERNAL_SERVER_ERROR)
    public ErreurRest calculImpactRuntimeException(Exception ex, WebRequest request) {
        return writeErrorResponse(ex, INTERNAL_SERVER_ERROR);
    }

    @org.springframework.web.bind.annotation.ExceptionHandler(value = {RuntimeException.class})
    @ResponseStatus(value = INTERNAL_SERVER_ERROR)
    public ErreurRest runtimeException(Exception ex, WebRequest request) {
        log.error("RuntimeException lors d'un traitement sur l'URI {}", request.getContextPath(), ex);
        log.debug("RuntimeException lors d'un traitement sur l'URI {}", request.getContextPath(), ex);
        return writeErrorResponse(new Exception("Erreur interne de traitement lors du traitement de la requête"), INTERNAL_SERVER_ERROR);
    }

    @org.springframework.web.bind.annotation.ExceptionHandler(value = {Exception.class})
    @ResponseStatus(value = INTERNAL_SERVER_ERROR)
    public ErreurRest exception(Exception ex, WebRequest request) {
        log.error("Exception lors d'un traitement sur l'URI {} : {}", request.getContextPath(), ex.getMessage());
        log.debug("Exception lors d'un traitement sur l'URI {}", request.getContextPath(), ex);
        return writeErrorResponse(new Exception("Erreur interne de traitement lors du traitement de la requête"), INTERNAL_SERVER_ERROR);
    }

}

