// Copyright 2016 The Bazel Authors. All rights reserved.
//
// Licensed 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 com.google.devtools.build.lib.bazel.repository.downloader;

import com.google.common.base.Strings;
import java.io.IOException;
import java.net.Authenticator;
import java.net.InetSocketAddress;
import java.net.PasswordAuthentication;
import java.net.Proxy;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.annotation.Nullable;

/**
 * Helper class for setting up a proxy server for network communication
 */
public class ProxyHelper {

  private final Map<String, String> env;

  /**
   * Creates new instance.
   *
   * @param env client environment to check for proxy settings
   */
  public ProxyHelper(Map<String, String> env) {
    this.env = env;
  }

  /**
   * This method takes a String for the resource being requested and sets up a proxy to make
   * the request if HTTP_PROXY and/or HTTPS_PROXY environment variables are set.
   *
   * @param requestedUrl remote resource that may need to be retrieved through a proxy
   */
  public Proxy createProxyIfNeeded(URL requestedUrl) throws IOException {
    String proxyAddress = null;
    String noProxyUrl = env.get("no_proxy");
    if (Strings.isNullOrEmpty(noProxyUrl)) {
      noProxyUrl = env.get("NO_PROXY");
    }
    if (!Strings.isNullOrEmpty(noProxyUrl)) {
      String[] noProxyUrlArray = noProxyUrl.split("\\s*,\\s*");
      String requestedHost = requestedUrl.getHost();
      for (int i = 0; i < noProxyUrlArray.length; i++) {
        if (noProxyUrlArray[i].startsWith(".")) {
          // This entry applies to sub-domains only.
          if (requestedHost.endsWith(noProxyUrlArray[i])) {
            return Proxy.NO_PROXY;
          }
        } else {
          // This entry applies to the literal hostname and sub-domains.
          if (requestedHost.equals(noProxyUrlArray[i])
              || requestedHost.endsWith("." + noProxyUrlArray[i])) {
            return Proxy.NO_PROXY;
          }
        }
      }
    }
    if (HttpUtils.isProtocol(requestedUrl, "https")) {
      proxyAddress = env.get("https_proxy");
      if (Strings.isNullOrEmpty(proxyAddress)) {
        proxyAddress = env.get("HTTPS_PROXY");
      }
    } else if (HttpUtils.isProtocol(requestedUrl, "http")) {
      proxyAddress = env.get("http_proxy");
      if (Strings.isNullOrEmpty(proxyAddress)) {
        proxyAddress = env.get("HTTP_PROXY");
      }
    }
    return createProxy(proxyAddress);
  }

  /**
   * This method takes a proxyAddress as a String (ex.
   * http://userId:password@proxyhost.domain.com:8000) and sets JVM arguments for http and https
   * proxy as well as returns a java.net.Proxy object for optional use.
   *
   * @param proxyAddress The fully qualified address of the proxy server
   * @return Proxy
   * @throws IOException
   */
  public static Proxy createProxy(@Nullable String proxyAddress) throws IOException {
    if (Strings.isNullOrEmpty(proxyAddress)) {
      return Proxy.NO_PROXY;
    }

    // Here there be dragons.
    Pattern urlPattern =
        Pattern.compile("^(https?)://(([^:@]+?)(?::([^@]+?))?@)?([^:]+)(?::(\\d+))?/?$");
    Matcher matcher = urlPattern.matcher(proxyAddress);
    if (!matcher.matches()) {
      throw new IOException("Proxy address " + proxyAddress + " is not a valid URL");
    }

    final String protocol = matcher.group(1);
    final String idAndPassword = matcher.group(2);
    final String username = matcher.group(3);
    final String password = matcher.group(4);
    final String hostname = matcher.group(5);
    final String portRaw = matcher.group(6);

    String cleanProxyAddress = proxyAddress;
    if (idAndPassword != null) {
      cleanProxyAddress =
          proxyAddress.replace(idAndPassword, ""); // Used to remove id+pwd from logging
    }

    boolean https;
    switch (protocol) {
      case "https":
        https = true;
        break;
      case "http":
        https = false;
        break;
      default:
        throw new IOException("Invalid proxy protocol for " + cleanProxyAddress);
    }

    int port = https ? 443 : 80; // Default port numbers

    if (portRaw != null) {
      try {
        port = Integer.parseInt(portRaw);
      } catch (NumberFormatException e) {
        throw new IOException("Error parsing proxy port: " + cleanProxyAddress, e);
      }
    }

    if (username != null) {
      if (password == null) {
        throw new IOException("No password given for proxy " + cleanProxyAddress);
      }

      // We need to make sure the proxy password is not url encoded; some special characters in
      // proxy passwords require url encoding for shells and other tools to properly consume.
      final String decodedPassword = URLDecoder.decode(password, "UTF-8");
      Authenticator.setDefault(
          new Authenticator() {
            @Override
            public PasswordAuthentication getPasswordAuthentication() {
              return new PasswordAuthentication(username, decodedPassword.toCharArray());
            }
          });
    }

    return new Proxy(Proxy.Type.HTTP, new InetSocketAddress(hostname, port));
  }
}
