package me.academeg.blog.api.exception.config;

import me.academeg.blog.api.common.*;
import me.academeg.blog.api.exception.AccountPermissionException;
import me.academeg.blog.api.exception.EntityExistException;
import me.academeg.blog.api.exception.EntityNotExistException;
import org.springframework.http.HttpStatus;
import org.springframework.security.oauth2.common.exceptions.OAuth2Exception;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
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.bind.annotation.RestController;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.stream.Collectors;

/**
 * GlobalExceptionHandler Configuration
 *
 * @author Yuriy A. Samsonov <yuriy.samsonov96@gmail.com>
 * @version 1.0
 */
@ControllerAdvice
@RestController
public class GlobalExceptionHandler {

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult handle(OAuth2Exception ex) {
        return new ApiResultImpl(1010, ex.getMessage());
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult handle(AccountPermissionException ex) {
        return new ApiResultImpl(2000, ex.getMessage());
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult handle(EntityExistException ex) {
        return new ApiResultImpl(3000, ex.getMessage());
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult handle(EntityNotExistException ex) {
        return new ApiResultImpl(4000, ex.getMessage());
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult handle(MethodArgumentNotValidException ex) {
        return new ApiResultWithData(
            4010,
            "Argument not valid",
            new MapResult<>(
                ex
                    .getBindingResult()
                    .getFieldErrors()
                    .stream()
                    .collect(Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage))
            )
        );
    }

    @ExceptionHandler
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ApiResult handle(ConstraintViolationException ex) {
        return new ApiResultWithData(
            4020,
            "Constraint exception",
            new CollectionResult<>(
                ex.
                    getConstraintViolations()
                    .stream()
                    .map(ConstraintViolation::getMessage)
                    .collect(Collectors.toList())
            )
        );
    }

//    @ExceptionHandler
//    @ResponseBody
//    @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
//    public ApiResult handle(Exception ex) {
//        return new ApiResultImpl(6000, "Internal Server Exception");
//    }
}

@@ -2004,34 +2004,36 @@
 piResultWithData
+%3C%3E
 (%0A
-
             4010
@@ -2257,77 +2257,205 @@
 ect(
-Collectors.toMap(FieldError::getField, FieldError::getDefaultMessage)
+%0A                        Collectors.toMap(%0A                            FieldError::getField,%0A                            FieldError::getDefaultMessage%0A                        )%0A                    
 )%0A  
@@ -2605,32 +2605,32 @@
 Exception ex) %7B%0A
-
         return n
@@ -2649,16 +2649,18 @@
 WithData
+%3C%3E
 (%0A      

fix exception handler