// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/net/firefox_proxy_settings.h"

#include "base/file_util.h"
#include "base/files/file_path.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_tokenizer.h"
#include "base/strings/string_util.h"
#include "base/values.h"
#include "chrome/common/importer/firefox_importer_utils.h"
#include "net/proxy/proxy_config.h"

namespace {

const char* const kNetworkProxyTypeKey = "network.proxy.type";
const char* const kHTTPProxyKey = "network.proxy.http";
const char* const kHTTPProxyPortKey = "network.proxy.http_port";
const char* const kSSLProxyKey = "network.proxy.ssl";
const char* const kSSLProxyPortKey = "network.proxy.ssl_port";
const char* const kFTPProxyKey = "network.proxy.ftp";
const char* const kFTPProxyPortKey = "network.proxy.ftp_port";
const char* const kGopherProxyKey = "network.proxy.gopher";
const char* const kGopherProxyPortKey = "network.proxy.gopher_port";
const char* const kSOCKSHostKey = "network.proxy.socks";
const char* const kSOCKSHostPortKey = "network.proxy.socks_port";
const char* const kSOCKSVersionKey = "network.proxy.socks_version";
const char* const kAutoconfigURL = "network.proxy.autoconfig_url";
const char* const kNoProxyListKey = "network.proxy.no_proxies_on";
const char* const kPrefFileName = "prefs.js";

FirefoxProxySettings::ProxyConfig IntToProxyConfig(int type) {
  switch (type) {
    case 1:
      return FirefoxProxySettings::MANUAL;
    case 2:
      return FirefoxProxySettings::AUTO_FROM_URL;
    case 4:
      return FirefoxProxySettings::AUTO_DETECT;
    case 5:
      return FirefoxProxySettings::SYSTEM;
    default:
      LOG(ERROR) << "Unknown Firefox proxy config type: " << type;
      return FirefoxProxySettings::NO_PROXY;
  }
}

FirefoxProxySettings::SOCKSVersion IntToSOCKSVersion(int type) {
  switch (type) {
    case 4:
      return FirefoxProxySettings::V4;
    case 5:
      return FirefoxProxySettings::V5;
    default:
      LOG(ERROR) << "Unknown Firefox proxy config type: " << type;
      return FirefoxProxySettings::UNKNONW;
  }
}

// Parses the prefs found in the file |pref_file| and puts the key/value pairs
// in |prefs|. Keys are strings, and values can be strings, booleans or
// integers.  Returns true if it succeeded, false otherwise (in which case
// |prefs| is not filled).
// Note: for strings, only valid UTF-8 string values are supported. If a
// key/pair is not valid UTF-8, it is ignored and will not appear in |prefs|.
bool ParsePrefFile(const base::FilePath& pref_file,
                   base::DictionaryValue* prefs) {
  // The string that is before a pref key.
  const std::string kUserPrefString = "user_pref(\"";
  std::string contents;
  if (!base::ReadFileToString(pref_file, &contents))
    return false;

  std::vector<std::string> lines;
  Tokenize(contents, "\n", &lines);

  for (std::vector<std::string>::const_iterator iter = lines.begin();
       iter != lines.end(); ++iter) {
    const std::string& line = *iter;
    size_t start_key = line.find(kUserPrefString);
    if (start_key == std::string::npos)
      continue;  // Could be a comment or a blank line.
    start_key += kUserPrefString.length();
    size_t stop_key = line.find('"', start_key);
    if (stop_key == std::string::npos) {
      LOG(ERROR) << "Invalid key found in Firefox pref file '" <<
          pref_file.value() << "' line is '" << line << "'.";
      continue;
    }
    std::string key = line.substr(start_key, stop_key - start_key);
    size_t start_value = line.find(',', stop_key + 1);
    if (start_value == std::string::npos) {
      LOG(ERROR) << "Invalid value found in Firefox pref file '" <<
          pref_file.value() << "' line is '" << line << "'.";
      continue;
    }
    size_t stop_value = line.find(");", start_value + 1);
    if (stop_value == std::string::npos) {
      LOG(ERROR) << "Invalid value found in Firefox pref file '" <<
          pref_file.value() << "' line is '" << line << "'.";
      continue;
    }
    std::string value = line.substr(start_value + 1,
                                    stop_value - start_value - 1);
    base::TrimWhitespace(value, base::TRIM_ALL, &value);
    // Value could be a boolean.
    bool is_value_true = LowerCaseEqualsASCII(value, "true");
    if (is_value_true || LowerCaseEqualsASCII(value, "false")) {
      prefs->SetBoolean(key, is_value_true);
      continue;
    }

    // Value could be a string.
    if (value.size() >= 2U &&
        value[0] == '"' && value[value.size() - 1] == '"') {
      value = value.substr(1, value.size() - 2);
      // ValueString only accept valid UTF-8.  Simply ignore that entry if it is
      // not UTF-8.
      if (base::IsStringUTF8(value))
        prefs->SetString(key, value);
      else
        VLOG(1) << "Non UTF8 value for key " << key << ", ignored.";
      continue;
    }

    // Or value could be an integer.
    int int_value = 0;
    if (base::StringToInt(value, &int_value)) {
      prefs->SetInteger(key, int_value);
      continue;
    }

    LOG(ERROR) << "Invalid value found in Firefox pref file '"
               << pref_file.value() << "' value is '" << value << "'.";
  }
  return true;
}

}  // namespace

FirefoxProxySettings::FirefoxProxySettings() {
  Reset();
}

FirefoxProxySettings::~FirefoxProxySettings() {
}

void FirefoxProxySettings::Reset() {
  config_type_ = NO_PROXY;
  http_proxy_.clear();
  http_proxy_port_ = 0;
  ssl_proxy_.clear();
  ssl_proxy_port_ = 0;
  ftp_proxy_.clear();
  ftp_proxy_port_ = 0;
  gopher_proxy_.clear();
  gopher_proxy_port_ = 0;
  socks_host_.clear();
  socks_port_ = 0;
  socks_version_ = UNKNONW;
  proxy_bypass_list_.clear();
  autoconfig_url_.clear();
}

// static
bool FirefoxProxySettings::GetSettings(FirefoxProxySettings* settings) {
  DCHECK(settings);
  settings->Reset();

  base::FilePath profile_path = GetFirefoxProfilePath();
  if (profile_path.empty())
    return false;
  base::FilePath pref_file = profile_path.AppendASCII(kPrefFileName);
  return GetSettingsFromFile(pref_file, settings);
}

bool FirefoxProxySettings::ToProxyConfig(net::ProxyConfig* config) {
  switch (config_type()) {
    case NO_PROXY:
      *config = net::ProxyConfig::CreateDirect();
      return true;
    case AUTO_DETECT:
      *config = net::ProxyConfig::CreateAutoDetect();
      return true;
    case AUTO_FROM_URL:
      *config = net::ProxyConfig::CreateFromCustomPacURL(
          GURL(autoconfig_url()));
      return true;
    case SYSTEM:
      // Can't convert this directly to a ProxyConfig.
      return false;
    case MANUAL:
      // Handled outside of the switch (since it is a lot of code.)
      break;
    default:
      NOTREACHED();
      return false;
  }

  // The rest of this funciton is for handling the MANUAL case.
  DCHECK_EQ(MANUAL, config_type());

  *config = net::ProxyConfig();
  config->proxy_rules().type =
      net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME;

  if (!http_proxy().empty()) {
    config->proxy_rules().proxies_for_http.SetSingleProxyServer(
        net::ProxyServer(
            net::ProxyServer::SCHEME_HTTP,
            net::HostPortPair(http_proxy(), http_proxy_port())));
  }

  if (!ftp_proxy().empty()) {
    config->proxy_rules().proxies_for_ftp.SetSingleProxyServer(
        net::ProxyServer(
            net::ProxyServer::SCHEME_HTTP,
            net::HostPortPair(ftp_proxy(), ftp_proxy_port())));
  }

  if (!ssl_proxy().empty()) {
    config->proxy_rules().proxies_for_https.SetSingleProxyServer(
        net::ProxyServer(
            net::ProxyServer::SCHEME_HTTP,
            net::HostPortPair(ssl_proxy(), ssl_proxy_port())));
  }

  if (!socks_host().empty()) {
    net::ProxyServer::Scheme proxy_scheme = V5 == socks_version() ?
        net::ProxyServer::SCHEME_SOCKS5 : net::ProxyServer::SCHEME_SOCKS4;

    config->proxy_rules().fallback_proxies.SetSingleProxyServer(
        net::ProxyServer(
            proxy_scheme,
            net::HostPortPair(socks_host(), socks_port())));
  }

  config->proxy_rules().bypass_rules.ParseFromStringUsingSuffixMatching(
      JoinString(proxy_bypass_list_, ';'));

  return true;
}

// static
bool FirefoxProxySettings::GetSettingsFromFile(const base::FilePath& pref_file,
                                               FirefoxProxySettings* settings) {
  base::DictionaryValue dictionary;
  if (!ParsePrefFile(pref_file, &dictionary))
    return false;

  int proxy_type = 0;
  if (!dictionary.GetInteger(kNetworkProxyTypeKey, &proxy_type))
    return true;  // No type means no proxy.

  settings->config_type_ = IntToProxyConfig(proxy_type);
  if (settings->config_type_ == AUTO_FROM_URL) {
    if (!dictionary.GetStringASCII(kAutoconfigURL,
                                   &(settings->autoconfig_url_))) {
      LOG(ERROR) << "Failed to retrieve Firefox proxy autoconfig URL";
    }
    return true;
  }

  if (settings->config_type_ == MANUAL) {
    if (!dictionary.GetStringASCII(kHTTPProxyKey, &(settings->http_proxy_)))
      LOG(ERROR) << "Failed to retrieve Firefox proxy HTTP host";
    if (!dictionary.GetInteger(kHTTPProxyPortKey,
                               &(settings->http_proxy_port_))) {
      LOG(ERROR) << "Failed to retrieve Firefox proxy HTTP port";
    }
    if (!dictionary.GetStringASCII(kSSLProxyKey, &(settings->ssl_proxy_)))
      LOG(ERROR) << "Failed to retrieve Firefox proxy SSL host";
    if (!dictionary.GetInteger(kSSLProxyPortKey, &(settings->ssl_proxy_port_)))
      LOG(ERROR) << "Failed to retrieve Firefox proxy SSL port";
    if (!dictionary.GetStringASCII(kFTPProxyKey, &(settings->ftp_proxy_)))
      LOG(ERROR) << "Failed to retrieve Firefox proxy FTP host";
    if (!dictionary.GetInteger(kFTPProxyPortKey, &(settings->ftp_proxy_port_)))
      LOG(ERROR) << "Failed to retrieve Firefox proxy SSL port";
    if (!dictionary.GetStringASCII(kGopherProxyKey, &(settings->gopher_proxy_)))
      LOG(ERROR) << "Failed to retrieve Firefox proxy gopher host";
    if (!dictionary.GetInteger(kGopherProxyPortKey,
                               &(settings->gopher_proxy_port_))) {
      LOG(ERROR) << "Failed to retrieve Firefox proxy gopher port";
    }
    if (!dictionary.GetStringASCII(kSOCKSHostKey, &(settings->socks_host_)))
      LOG(ERROR) << "Failed to retrieve Firefox SOCKS host";
    if (!dictionary.GetInteger(kSOCKSHostPortKey, &(settings->socks_port_)))
      LOG(ERROR) << "Failed to retrieve Firefox SOCKS port";
    int socks_version;
    if (dictionary.GetInteger(kSOCKSVersionKey, &socks_version))
      settings->socks_version_ = IntToSOCKSVersion(socks_version);

    std::string proxy_bypass;
    if (dictionary.GetStringASCII(kNoProxyListKey, &proxy_bypass) &&
        !proxy_bypass.empty()) {
      base::StringTokenizer string_tok(proxy_bypass, ",");
      while (string_tok.GetNext()) {
        std::string token = string_tok.token();
        base::TrimWhitespaceASCII(token, base::TRIM_ALL, &token);
        if (!token.empty())
          settings->proxy_bypass_list_.push_back(token);
      }
    }
  }
  return true;
}
