/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.apache.drill.exec.server.rest.auth;

import org.apache.drill.shaded.guava.com.google.common.base.Preconditions;
import org.apache.drill.common.config.DrillConfig;
import org.apache.drill.common.exceptions.DrillException;
import org.apache.drill.common.map.CaseInsensitiveMap;
import org.apache.drill.common.scanner.persistence.ScanResult;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.exception.DrillbitStartupException;
import org.apache.drill.exec.rpc.security.AuthStringUtil;
import org.apache.drill.exec.server.DrillbitContext;
import org.apache.drill.exec.server.rest.WebServerConstants;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.security.ConstraintSecurityHandler;
import org.eclipse.jetty.security.authentication.SessionAuthentication;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.util.security.Constraint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;


public class DrillHttpSecurityHandlerProvider extends ConstraintSecurityHandler {
  private static final Logger logger = LoggerFactory.getLogger(DrillHttpSecurityHandlerProvider.class);

  private final Map<String, DrillHttpConstraintSecurityHandler> securityHandlers =
      CaseInsensitiveMap.newHashMapWithExpectedSize(2);

  @SuppressWarnings("unchecked")
  public DrillHttpSecurityHandlerProvider(DrillConfig config, DrillbitContext drillContext)
      throws DrillbitStartupException {

    Preconditions.checkState(config.getBoolean(ExecConstants.USER_AUTHENTICATION_ENABLED));
    final Set<String> configuredMechanisms = getHttpAuthMechanisms(config);

    final ScanResult scan = drillContext.getClasspathScan();
    final Collection<Class<? extends DrillHttpConstraintSecurityHandler>> factoryImpls =
        scan.getImplementations(DrillHttpConstraintSecurityHandler.class);
    logger.debug("Found DrillHttpConstraintSecurityHandler implementations: {}", factoryImpls);

    for (final Class<? extends DrillHttpConstraintSecurityHandler> clazz : factoryImpls) {

      // If all the configured mechanisms handler is added then break out of this loop
      if (configuredMechanisms.isEmpty()) {
        break;
      }

      Constructor<? extends DrillHttpConstraintSecurityHandler> validConstructor = null;
      for (final Constructor<?> c : clazz.getConstructors()) {
        final Class<?>[] params = c.getParameterTypes();
        if (params.length == 0) {
          validConstructor = (Constructor<? extends DrillHttpConstraintSecurityHandler>) c; // unchecked
          break;
        }
      }

      if (validConstructor == null) {
        logger.warn("Skipping DrillHttpConstraintSecurityHandler class {}. It must implement at least one" +
            " constructor with signature [{}()]", clazz.getCanonicalName(), clazz.getName());
        continue;
      }

      try {
        final DrillHttpConstraintSecurityHandler instance = validConstructor.newInstance();
        if (configuredMechanisms.remove(instance.getImplName())) {
          instance.doSetup(drillContext);
          securityHandlers.put(instance.getImplName(), instance);
        }
      } catch (IllegalArgumentException | ReflectiveOperationException | DrillException e) {
        logger.warn(String.format("Failed to create DrillHttpConstraintSecurityHandler of type '%s'",
            clazz.getCanonicalName()), e);
      }
    }

    if (securityHandlers.size() == 0) {
      throw new DrillbitStartupException(
          "Authentication is enabled for WebServer but none of the security mechanism " +
          "was configured properly. Please verify the configurations and try again.");
    }

    logger.info("Configure auth mechanisms for WebServer are: {}", securityHandlers.keySet());
  }

  @Override
  public void doStart() throws Exception {
    super.doStart();
    for (DrillHttpConstraintSecurityHandler securityHandler : securityHandlers.values()) {
      securityHandler.doStart();
    }
  }

  @Override
  public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
      throws IOException, ServletException {

    Preconditions.checkState(securityHandlers.size() > 0);

    HttpSession session = request.getSession(true);
    SessionAuthentication authentication =
        (SessionAuthentication) session.getAttribute(SessionAuthentication.__J_AUTHENTICATED);
    String uri = request.getRequestURI();
    final DrillHttpConstraintSecurityHandler securityHandler;

    // Before authentication, all requests go through the FormAuthenticator if configured except for /spnegoLogin
    // request. For SPNEGO authentication all requests will be forced going via /spnegoLogin before authentication is
    // done, this is to ensure that we don't have to authenticate same client session multiple times for each resource.
    //
    // If this authentication is null, user hasn't logged in yet
    if (authentication == null) {

      // 1) If only SPNEGOSecurity handler then use SPNEGOSecurity
      // 2) If both but uri equals spnegoLogin then use SPNEGOSecurity
      // 3) If both but uri doesn't equals spnegoLogin then use FORMSecurity
      // 4) If only FORMSecurity handler then use FORMSecurity
      if (isSpnegoEnabled() && (!isFormEnabled() || uri.equals(WebServerConstants.SPENGO_LOGIN_RESOURCE_PATH))) {
        securityHandler = securityHandlers.get(Constraint.__SPNEGO_AUTH);
        securityHandler.handle(target, baseRequest, request, response);
      } else if(isBasicEnabled() && request.getHeader(HttpHeader.AUTHORIZATION.asString()) != null) {
        securityHandler = securityHandlers.get(Constraint.__BASIC_AUTH);
        securityHandler.handle(target, baseRequest, request, response);
      } else if (isFormEnabled()) {
        securityHandler = securityHandlers.get(Constraint.__FORM_AUTH);
        securityHandler.handle(target, baseRequest, request, response);
      }

    }
    // If user has logged in, use the corresponding handler to handle the request
    else {
      final String authMethod = authentication.getAuthMethod();
      securityHandler = securityHandlers.get(authMethod);
      securityHandler.handle(target, baseRequest, request, response);
    }
  }

  @Override
  public void setHandler(Handler handler) {
    super.setHandler(handler);
    for (DrillHttpConstraintSecurityHandler securityHandler : securityHandlers.values()) {
      securityHandler.setHandler(handler);
    }
  }

  @Override
  public void doStop() throws Exception {
    super.doStop();
    for (DrillHttpConstraintSecurityHandler securityHandler : securityHandlers.values()) {
      securityHandler.doStop();
    }
  }

  public boolean isSpnegoEnabled() {
    return securityHandlers.containsKey(Constraint.__SPNEGO_AUTH);
  }

  public boolean isFormEnabled() {
    return securityHandlers.containsKey(Constraint.__FORM_AUTH);
  }

  public boolean isBasicEnabled() {
    return securityHandlers.containsKey(Constraint.__BASIC_AUTH);
  }

  /**
   * Returns a list of configured mechanisms for HTTP authentication. For backward
   * compatibility if authentication is enabled it will include FORM mechanism by default.
   * @param config - {@link DrillConfig}
   * @return
   */
  public static Set<String> getHttpAuthMechanisms(DrillConfig config) {
    final Set<String> configuredMechs = new HashSet<>();
    final boolean authEnabled = config.getBoolean(ExecConstants.USER_AUTHENTICATION_ENABLED);

    if (authEnabled) {
      if (config.hasPath(ExecConstants.HTTP_AUTHENTICATION_MECHANISMS)) {
        configuredMechs.addAll(
            AuthStringUtil.asSet(config.getStringList(ExecConstants.HTTP_AUTHENTICATION_MECHANISMS)));
      } else {
        // For backward compatibility
        configuredMechs.add(Constraint.__FORM_AUTH);
      }
    }
    return configuredMechs;
  }
}
