class SamlEngineExceptionMapper implements ExceptionMapper<Exception> {

    @Override
    public Response toResponse(Exception exception) {
        final UUID errorId = UUID.randomUUID();
        Response.ResponseBuilder response = Response.status(Response.Status.BAD_REQUEST);

        // when creating a new exception here we want to create an unaudited application exception - this is to ensure
        // that the exception is audited by the calling application, as saml-engine no longer talks directly to
        // event sink

        if(exception instanceof ApplicationException) {
            ApplicationException applicationException = (ApplicationException)exception;
            response.entity(logAndGetErrorStatusDto(applicationException.getExceptionType().getLevel(), applicationException.getExceptionType(), applicationException, applicationException.getErrorId(), applicationException.isAudited()));
        } else if(exception instanceof SamlContextException) {
            SamlContextException contextException = (SamlContextException) exception;
            response.entity(logAndGetErrorStatusDto(contextException.getLogLevel(), contextException.getExceptionType(), exception, errorId, HAS_NOT_BEEN_AUDITED_YET));
        } else if(exception instanceof SamlFailedToDecryptException) {
            response.entity(logAndGetErrorStatusDto(((SamlFailedToDecryptException) exception).getLogLevel(), ExceptionType.INVALID_SAML_FAILED_TO_DECRYPT, exception, errorId, HAS_NOT_BEEN_AUDITED_YET));
        } else if(exception instanceof SamlDuplicateRequestIdException) {
            response.entity(logAndGetErrorStatusDto(((SamlDuplicateRequestIdException) exception).getLogLevel(), ExceptionType.INVALID_SAML_DUPLICATE_REQUEST_ID, exception, errorId, HAS_NOT_BEEN_AUDITED_YET));
        } else if(exception instanceof SamlRequestTooOldException) {
            response.entity(logAndGetErrorStatusDto(((SamlTransformationErrorException) exception).getLogLevel(), ExceptionType.INVALID_SAML_REQUEST_TOO_OLD, exception, errorId, HAS_NOT_BEEN_AUDITED_YET));
        } else if(exception instanceof SamlTransformationErrorException) {
            response.entity(logAndGetErrorStatusDto(((SamlTransformationErrorException) exception).getLogLevel(), ExceptionType.INVALID_SAML, exception, errorId, HAS_NOT_BEEN_AUDITED_YET));
        } else if(exception instanceof UnableToGenerateSamlException) {
            response.entity(logAndGetErrorStatusDto(((UnableToGenerateSamlException) exception).getLogLevel(), ExceptionType.INVALID_INPUT, exception, errorId, HAS_NOT_BEEN_AUDITED_YET));
        } else if (exception instanceof NoKeyConfiguredForEntityException) {
            response.entity(logAndGetErrorStatusDto(ERROR, ExceptionType.NO_KEY_CONFIGURED_FOR_ENTITY, exception, errorId, HAS_NOT_BEEN_AUDITED_YET));
        } else {
            levelLogger.log(WARN, exception, errorId);
        }

        return response.build();
    }

    @Inject public  SamlEngineExceptionMapper(final LevelLoggerFactory<SamlEngineExceptionMapper> levelLoggerFactory);

}