content: package com.github.aesteve.vertx.nubes.reflections.factories;
  
  import com.github.aesteve.vertx.nubes.Config;
  import com.github.aesteve.vertx.nubes.annotations.auth.Auth;
  import com.github.aesteve.vertx.nubes.auth.AuthMethod;
  import com.github.aesteve.vertx.nubes.handlers.impl.CheckTokenHandler;
  import io.vertx.core.Handler;
  import io.vertx.ext.auth.AuthProvider;
  import io.vertx.ext.auth.jwt.JWTAuth;
  import io.vertx.ext.web.RoutingContext;
  import io.vertx.ext.web.handler.BasicAuthHandler;
  import io.vertx.ext.web.handler.JWTAuthHandler;
  import io.vertx.ext.web.handler.RedirectAuthHandler;
  
  import java.util.EnumMap;
  import java.util.Map;
  import java.util.function.Function;
  
  import static com.github.aesteve.vertx.nubes.auth.AuthMethod.*;
  
  public class AuthenticationFactory {
  
    private final Config config;
    private Map<AuthMethod, Function<AuthProvider, Handler<RoutingContext>>> authHandlers;
  
    public AuthenticationFactory(Config config) {
      this.config = config;
      authHandlers = new EnumMap<>(AuthMethod.class);
      authHandlers.put(BASIC, BasicAuthHandler::create);
      authHandlers.put(JWT, auth -> JWTAuthHandler.create((JWTAuth)config.getAuthProvider()));
      authHandlers.put(API_TOKEN, CheckTokenHandler::new);
    }
  
    public Handler<RoutingContext> create(Auth auth) {
      final AuthProvider authProvider = config.getAuthProvider();
      if (authProvider == null) {
        return null;
      }
      final AuthMethod authMethod = auth.method();
      Function<AuthProvider, Handler<RoutingContext>> authHandlerCreator = authHandlers.get(authMethod);
      if (authHandlerCreator == null && authMethod == REDIRECT) {
        final String redirect = auth.redirectURL();
        if ("".equals(redirect)) {
          throw new IllegalArgumentException("You must specify a redirectURL if you're using Redirect Auth");
        }
        return RedirectAuthHandler.create(authProvider, redirect);
      } else if (authHandlerCreator == null) {
        throw new UnsupportedOperationException();
      }
      return authHandlerCreator.apply(authProvider);
    }
  }
  