/*
 * 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.store.http;

import com.fasterxml.jackson.annotation.JsonInclude;
import org.apache.drill.common.PlanStringBuilder;
import org.apache.drill.common.exceptions.UserException;
import org.apache.drill.common.logical.OAuthConfig;
import org.apache.drill.common.map.CaseInsensitiveMap;
import org.apache.drill.common.logical.StoragePluginConfig;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonTypeName;
import org.apache.drill.exec.store.security.CredentialProviderUtils;
import org.apache.drill.common.logical.security.CredentialsProvider;
import org.apache.drill.exec.store.security.UsernamePasswordWithProxyCredentials;
import org.apache.drill.exec.store.security.oauth.OAuthTokenCredentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;


@JsonTypeName(HttpStoragePluginConfig.NAME)
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
public class HttpStoragePluginConfig extends StoragePluginConfig {
  private static final Logger logger = LoggerFactory.getLogger(HttpStoragePluginConfig.class);
  private static final int DEFAULT_RATE_LIMIT = 1000;
  public static final String NAME = "http";

  public final Map<String, HttpApiConfig> connections;
  public final boolean cacheResults;
  public final String proxyHost;
  public final int proxyPort;
  public final String proxyType;
  public final boolean enableEnhancedParamSyntax;
  /**
   * Timeout in {@link TimeUnit#SECONDS}.
   */
  public final int timeout;
  public final int retryDelay;

  @JsonCreator
  public HttpStoragePluginConfig(@JsonProperty("cacheResults") Boolean cacheResults,
                                 @JsonProperty("enhanced") Boolean enableEnhancedParamSyntax,
                                 @JsonProperty("connections") Map<String, HttpApiConfig> connections,
                                 @JsonProperty("timeout") Integer timeout,
                                 @JsonProperty("retryDelay") Integer retryDelay,
                                 @JsonProperty("username") String username,
                                 @JsonProperty("password") String password,
                                 @JsonProperty("proxyHost") String proxyHost,
                                 @JsonProperty("proxyPort") Integer proxyPort,
                                 @JsonProperty("proxyType") String proxyType,
                                 @JsonProperty("proxyUsername") String proxyUsername,
                                 @JsonProperty("proxyPassword") String proxyPassword,
                                 @JsonProperty("oAuthConfig") OAuthConfig oAuthConfig,
                                 @JsonProperty("credentialsProvider") CredentialsProvider credentialsProvider,
                                 @JsonProperty("authMode") String authMode
                                 ) {
    super(CredentialProviderUtils.getCredentialsProvider(
        null,
        null,
        null,
        normalize(username),
        normalize(password),
        normalize(proxyUsername),
        normalize(proxyPassword),
        credentialsProvider),
        credentialsProvider == null,
        AuthMode.parseOrDefault(authMode, AuthMode.SHARED_USER),
      oAuthConfig);
    this.cacheResults = cacheResults != null && cacheResults;
    this.enableEnhancedParamSyntax = enableEnhancedParamSyntax != null && enableEnhancedParamSyntax;
    this.retryDelay = (retryDelay == null || retryDelay < 0) ? DEFAULT_RATE_LIMIT : retryDelay;

    this.connections = CaseInsensitiveMap.newHashMap();
    if (connections != null) {
      this.connections.putAll(connections);
    }

    this.timeout = timeout == null ? 0 : timeout;
    this.proxyHost = normalize(proxyHost);
    this.proxyPort = proxyPort == null ? 0 : proxyPort;

    proxyType = normalize(proxyType);
    this.proxyType = proxyType == null
        ? "direct" : proxyType.trim().toLowerCase();

    // Validate Proxy Type
    switch (this.proxyType) {
      case "direct":
      case "http":
      case "socks":
        break;
      default:
        throw UserException
          .validationError()
          .message("Invalid Proxy Type: %s.  Drill supports 'direct', 'http' and 'socks' proxies.", proxyType)
          .build(logger);
    }
  }

  private HttpStoragePluginConfig(HttpStoragePluginConfig that, CredentialsProvider credentialsProvider) {
    super(credentialsProvider, credentialsProvider == null, that.authMode);
    this.cacheResults = that.cacheResults;
    this.enableEnhancedParamSyntax = that.enableEnhancedParamSyntax;
    this.connections = that.connections;
    this.timeout = that.timeout;
    this.proxyHost = that.proxyHost;
    this.proxyPort = that.proxyPort;
    this.proxyType = that.proxyType;
    this.oAuthConfig = that.oAuthConfig;
    this.retryDelay = that.retryDelay;
  }

  /**
   * Clone constructor used for updating OAuth tokens
   * @param that The current HTTP Plugin Config
   * @param oAuthConfig The updated OAuth config
   */
  public HttpStoragePluginConfig(HttpStoragePluginConfig that, OAuthConfig oAuthConfig) {
    super(CredentialProviderUtils.getCredentialsProvider(that.proxyUsername(), that.proxyPassword(), that.credentialsProvider),
      that.credentialsProvider == null);

    this.cacheResults = that.cacheResults;
    this.enableEnhancedParamSyntax = that.enableEnhancedParamSyntax;
    this.connections = that.connections;
    this.timeout = that.timeout;
    this.proxyHost = that.proxyHost;
    this.proxyPort = that.proxyPort;
    this.proxyType = that.proxyType;
    this.oAuthConfig = that.oAuthConfig;
    this.retryDelay = that.retryDelay;
  }

  private static String normalize(String value) {
    if (value == null) {
      return value;
    }
    value = value.trim();
    return value.isEmpty() ? null : value;
  }

  /**
   * Create a copy of the plugin config with only the indicated connection.
   * The copy is used in the query plan to avoid including unnecessary information.
   */
  public HttpStoragePluginConfig copyForPlan(String connectionName) {
    Optional<UsernamePasswordWithProxyCredentials> creds = getUsernamePasswordCredentials();
    return new HttpStoragePluginConfig(
      cacheResults,
      enableEnhancedParamSyntax,
      configFor(connectionName),
      timeout, retryDelay,
      username(),
      password(),
      proxyHost,
      proxyPort,
      proxyType,
      proxyUsername(),
      proxyPassword(),
      oAuthConfig,
      credentialsProvider,
      authMode.name()
    );
  }

  private Map<String, HttpApiConfig> configFor(String connectionName) {
    Map<String, HttpApiConfig> single = new HashMap<>();
    single.put(connectionName, getConnection(connectionName));
    return single;
  }

  @Override
  public boolean equals(Object that) {
    if (this == that) {
      return true;
    } else if (that == null || getClass() != that.getClass()) {
      return false;
    }
    HttpStoragePluginConfig thatConfig = (HttpStoragePluginConfig) that;
    return Objects.equals(connections, thatConfig.connections) &&
      Objects.equals(cacheResults, thatConfig.cacheResults) &&
      Objects.equals(enableEnhancedParamSyntax, thatConfig.enableEnhancedParamSyntax) &&
      Objects.equals(proxyHost, thatConfig.proxyHost) &&
      Objects.equals(retryDelay, thatConfig.retryDelay) &&
      Objects.equals(proxyPort, thatConfig.proxyPort) &&
      Objects.equals(proxyType, thatConfig.proxyType) &&
      Objects.equals(oAuthConfig, thatConfig.oAuthConfig) &&
      Objects.equals(credentialsProvider, thatConfig.credentialsProvider) &&
      Objects.equals(authMode, thatConfig.authMode);
  }

  @Override
  public String toString() {
    return new PlanStringBuilder(this)
      .field("connections", connections)
      .field("cacheResults", cacheResults)
      .field("enhanced", enableEnhancedParamSyntax)
      .field("timeout", timeout)
      .field("retryDelay", retryDelay)
      .field("proxyHost", proxyHost)
      .field("proxyPort", proxyPort)
      .field("credentialsProvider", credentialsProvider)
      .field("oauthConfig", oAuthConfig)
      .field("proxyType", proxyType)
      .field("authMode", authMode)
      .toString();
  }

  @Override
  public int hashCode() {
    return Objects.hash(connections, cacheResults, enableEnhancedParamSyntax, timeout, retryDelay,
        proxyHost, proxyPort, proxyType, oAuthConfig, credentialsProvider, authMode);
  }

  @JsonProperty("cacheResults")
  public boolean cacheResults() { return cacheResults; }

  @JsonProperty("enhanced")
  public boolean enableEnhancedParamSyntax() { return enableEnhancedParamSyntax; }

  @JsonProperty("connections")
  public Map<String, HttpApiConfig> connections() { return connections; }

  @JsonProperty("timeout")
  public int timeout() { return timeout;}

  @JsonProperty("retryDelay")
  public int retryDelay() {
    return retryDelay;
  }

   @JsonProperty("proxyHost")
  public String proxyHost() { return proxyHost; }

  @JsonProperty("proxyPort")
  public int proxyPort() { return proxyPort; }

  @JsonProperty("username")
  public String username() {
    if (!directCredentials) {
      return null;
    }
    return getUsernamePasswordCredentials()
      .map(UsernamePasswordWithProxyCredentials::getUsername)
      .orElse(null);
  }

  @JsonProperty("password")
  public String password() {
    if (!directCredentials) {
      return null;
    }
    return getUsernamePasswordCredentials()
      .map(UsernamePasswordWithProxyCredentials::getPassword)
      .orElse(null);
  }

  @JsonProperty("proxyUsername")
  public String proxyUsername() {
    if (!directCredentials) {
      return null;
    }
    return getUsernamePasswordCredentials()
      .map(UsernamePasswordWithProxyCredentials::getProxyUsername)
      .orElse(null);
  }

  @JsonProperty("proxyPassword")
  public String proxyPassword() {
    if (!directCredentials) {
      return null;
    }
    return getUsernamePasswordCredentials()
      .map(UsernamePasswordWithProxyCredentials::getProxyPassword)
      .orElse(null);
  }

  @JsonIgnore
  private static String getClientID(OAuthTokenCredentials credentials) {
    return credentials.getClientID();
  }

  @JsonIgnore
  private static String getClientSecret(OAuthTokenCredentials credentials) {
    return credentials.getClientSecret();
  }

  @JsonIgnore
  private static String getTokenURL(OAuthTokenCredentials credentials) {
    return credentials.getTokenUri();
  }

  @JsonProperty("proxyType")
  public String proxyType() { return proxyType; }

  @JsonIgnore
  public HttpApiConfig getConnection(String connectionName) {
    return connections.get(connectionName);
  }

  @JsonIgnore
  public Optional<UsernamePasswordWithProxyCredentials> getUsernamePasswordCredentials() {
    return new UsernamePasswordWithProxyCredentials.Builder()
      .setCredentialsProvider(credentialsProvider)
      .build();
  }

  @JsonIgnore
  public Optional<UsernamePasswordWithProxyCredentials> getUsernamePasswordCredentials(String username) {
    return new UsernamePasswordWithProxyCredentials.Builder()
      .setCredentialsProvider(credentialsProvider)
      .setQueryUser(username)
      .build();
  }

  @JsonIgnore
  public static Optional<OAuthTokenCredentials> getOAuthCredentials(CredentialsProvider credentialsProvider) {
    return new OAuthTokenCredentials.Builder()
      .setCredentialsProvider(credentialsProvider)
      .build();
  }

  @Override
  public HttpStoragePluginConfig updateCredentialProvider(CredentialsProvider credentialsProvider) {
    return new HttpStoragePluginConfig(this, credentialsProvider);
  }
}
