package com.ffii.core.support;

import java.util.UUID;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.server.ResponseStatusException;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

import com.ffii.core.exception.ConflictException;
import com.ffii.core.exception.InternalServerErrorException;
import com.ffii.core.response.ErrorRes;
import com.ffii.core.response.FailureRes;

@RestControllerAdvice
public class ErrorHandler extends ResponseEntityExceptionHandler {
  private final Log logger = LogFactory.getLog(getClass());

  @ExceptionHandler({ ConflictException.class, ResponseStatusException.class })
  public ResponseEntity<FailureRes> error409422(final Exception ex) {
    ResponseStatusException e = (ResponseStatusException) ex;
    return new ResponseEntity<>(new FailureRes(e.getReason()), e.getStatusCode());
  }

  @ExceptionHandler(AccessDeniedException.class)
  public ResponseEntity<?> error403(final Exception ex) {
    return ResponseEntity.status(HttpStatus.FORBIDDEN).build();
  }

  @ExceptionHandler({ InternalServerErrorException.class, Exception.class })
  @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
  public ResponseEntity<ErrorRes> error500(final Exception ex) {
    UUID traceId = UUID.randomUUID();
    logger.error("traceId: " + traceId, ex);
    return new ResponseEntity<>(new ErrorRes(traceId.toString()), HttpStatus.INTERNAL_SERVER_ERROR);
  }

}
