package pwc.taxtech.atms.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;
import pwc.taxtech.atms.exception.ApiException;
import pwc.taxtech.atms.exception.ApplicationException;
import pwc.taxtech.atms.exception.ServiceException;

@EnableWebMvc
@ControllerAdvice
public class AtmsExceptionHandler extends ResponseEntityExceptionHandler {
    private static Logger LOGGER = LoggerFactory.getLogger(AtmsExceptionHandler.class);

    @ExceptionHandler(value = {
            ApplicationException.class,
            ServiceException.class,
            ApiException.class
    })
    protected ResponseEntity<Object> handleExceptions(Exception ex) throws ServiceException {
        LOGGER.error("Rest Exception!", ex);
        ex.printStackTrace();
        if (ex.getMessage() != null) {
            LOGGER.debug("Rest Exception for {}", ex.getMessage());
            LOGGER.info("Rest Exception for {]", ex.getMessage());
        }

        if (ex instanceof ApplicationException) {
            ex.printStackTrace();
            return handleApplicationException((ApplicationException) ex);
        } else if (ex instanceof ServiceException) {
            ex.printStackTrace();
            return handleServiceException((ServiceException) ex);
        } else if (ex instanceof ApiException) {
            ex.printStackTrace();
            return ((ApiException) ex).handle();
        } else {
            ex.printStackTrace();
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
        }
    }

    private ResponseEntity<Object> handleApplicationException(ApplicationException ex) {
        throw ex;
    }

    private ResponseEntity<Object> handleServiceException(ServiceException ex) throws ServiceException {
        throw ex;
    }

}