package at.ac.tuwien.inso.controller;

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.TypeMismatchException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.context.i18n.LocaleContextHolder;
import org.springframework.dao.DataAccessException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.servlet.ModelAndView;

import at.ac.tuwien.inso.exception.ActionNotAllowedException;
import at.ac.tuwien.inso.exception.BusinessObjectNotFoundException;
import at.ac.tuwien.inso.exception.ValidationException;


@ControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger logger = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    @Autowired
    private MessageSource messageSource;

    @ExceptionHandler(Exception.class)
    @ResponseStatus(value=HttpStatus.NOT_FOUND)
    public ModelAndView handlerExceptions(HttpServletRequest request, Exception exception) {
        logger.warn("Arbitrary exception happened", exception);
        ModelAndView mav = new ModelAndView();
        mav.setViewName("error");
        return mav;
    }

    @ExceptionHandler(DataAccessException.class)
    @ResponseStatus(value=HttpStatus.CONFLICT)
    public ModelAndView handleDataAccessExceptions(HttpServletRequest request, DataAccessException ex) {
        logger.warn("DataAccessException: " + request.getRequestURL(), ex);
        ModelAndView mav = new ModelAndView();
        mav.setViewName("error");
        return mav;
    }

    @ExceptionHandler(BusinessObjectNotFoundException.class)
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    public ModelAndView handleBusinessObjectNotFoundExceptions(HttpServletRequest request, BusinessObjectNotFoundException ex) {
        logger.warn("BusinessObjectNotFoundException: " + request.getRequestURL(), ex);
        ModelAndView mav = new ModelAndView();
        mav.setViewName("error");
        return mav;
    }

    @ExceptionHandler(ValidationException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public ModelAndView handleValidationExceptions(HttpServletRequest request, ValidationException ex) {
        logger.warn("ValidationException: " + request.getRequestURL(), ex);
        ModelAndView mav = new ModelAndView();
        mav.setViewName("error");
        return mav;
    }

    @ExceptionHandler(ActionNotAllowedException.class)
    @ResponseStatus(value = HttpStatus.FORBIDDEN)
    public ModelAndView handleActionNotAllowedExceptions(HttpServletRequest request, ActionNotAllowedException ex) {
        logger.warn("ActionNotAllowedException: " + request.getRequestURL(), ex);
        ModelAndView mav = new ModelAndView();
        mav.setViewName("error");
        return mav;
    }

    @ExceptionHandler(TypeMismatchException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    public ModelAndView handleTypeMismatchExceptions(HttpServletRequest request, TypeMismatchException ex) {
        logger.warn("TypeMismatchRequest: " + request.getRequestURL(), ex);
        ModelAndView mav = new ModelAndView();
        mav.setViewName("error");
        return mav;
    }
}

@@ -709,16 +709,42 @@
 dView;%0A%0A
+import java.util.Locale;%0A%0A
 import a
@@ -789,32 +789,32 @@
 lowedException;%0A
-
 import at.ac.tuw
@@ -857,32 +857,88 @@
 FoundException;%0A
+import at.ac.tuwien.inso.exception.UserFacingException;%0A
 import at.ac.tuw
@@ -1262,33 +1262,35 @@
 =HttpStatus.
-NOT_FOUND
+BAD_REQUEST
 )%0A    public
@@ -2296,32 +2296,83 @@
 ModelAndView();%0A
+        mav.addObject(%22message%22, ex.getMessage());%0A
         mav.setV
@@ -3498,32 +3498,32 @@
 uestURL(), ex);%0A
-
         ModelAnd
@@ -3612,11 +3612,575 @@
 v;%0A    %7D
+%0A%0A    @ExceptionHandler(UserFacingException.class)%0A    @ResponseStatus(value = HttpStatus.NOT_FOUND)%0A    public ModelAndView handleUserFacingException(HttpServletRequest request, UserFacingException ex) %7B%0A        logger.warn(%22UserFacingException: %22 + request.getRequestURL(), ex);%0A%0A        ModelAndView mav = new ModelAndView();%0A%0A        Locale locale = LocaleContextHolder.getLocale();%0A        String msg = messageSource.getMessage(ex.getMessage(), null, locale);%0A        mav.addObject(%22message%22, msg);%0A%0A        mav.setViewName(%22error%22);%0A        return mav;%0A    %7D
 %0A%7D%0A

Handle UserFacingExceptions differently