// Copyright (c) 2011 The Chromium OS 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 "update_engine/chrome_proxy_resolver.h"

#include <base/json/json_reader.h>
#include <base/memory/scoped_ptr.h>
#include <base/values.h>

#include "update_engine/utils.h"

using google::protobuf::Closure;
using google::protobuf::NewCallback;
using std::deque;
using std::string;
using std::vector;

namespace chromeos_update_engine {

const char kSessionManagerService[] = "org.chromium.SessionManager";
const char kSessionManagerPath[] = "/org/chromium/SessionManager";
const char kSessionManagerInterface[] = "org.chromium.SessionManagerInterface";
const char kSessionManagerRetrievePropertyMethod[] =
    "RetrieveProperty";
const char kSessionManagerProxySettingsKey[] = "cros.proxy.everywhere";

bool ChromeProxyResolver::GetProxiesForUrl(
    const std::string& url,
    ProxiesResolvedFn callback,
    void* data) {
  ChromeProxyResolverClosureArgs args;
  args.url = url;
  args.callback = callback;
  args.data = data;
  Closure* closure = NewCallback(this,
                                 &ChromeProxyResolver::GetProxiesForUrlCallback,
                                 args);
  g_idle_add(utils::GlibRunClosure, closure);
  return true;
}

void ChromeProxyResolver::GetProxiesForUrlCallback(
    ChromeProxyResolverClosureArgs args) {
  deque<string> proxies;
  // First, query dbus for the currently stored settings
  DBusGProxy* proxy = DbusProxy();
  if (proxy) {
    string json_settings;
    if (GetJsonProxySettings(proxy, &json_settings)) {
      LOG(INFO) << "got settings:" << json_settings;
      GetProxiesForUrlWithSettings(args.url, json_settings, &proxies);
    }
  }
  (*args.callback)(proxies, args.data);
}

bool ChromeProxyResolver::GetJsonProxySettings(DBusGProxy* proxy,
                                               std::string* out_json) {
  gchar* value = NULL;
  GArray* sig = NULL;
  GError* error = NULL;
  TEST_AND_RETURN_FALSE(
      dbus_->ProxyCall(proxy,
                       kSessionManagerRetrievePropertyMethod,
                       &error,
                       G_TYPE_STRING, kSessionManagerProxySettingsKey,
                       G_TYPE_INVALID,
                       G_TYPE_STRING, &value,
                       DBUS_TYPE_G_UCHAR_ARRAY, &sig,
                       G_TYPE_INVALID));
  g_array_free(sig, false);
  out_json->assign(value);
  g_free(value);
  return true;
}

DBusGProxy* ChromeProxyResolver::DbusProxy() {
  GError* error = NULL;
  DBusGConnection* bus = dbus_->BusGet(DBUS_BUS_SYSTEM, &error);
  if (!bus) {
    LOG(ERROR) << "Failed to get System Dbus: "
               << utils::GetAndFreeGError(&error);
    return NULL;
  }
  DBusGProxy* proxy = dbus_->ProxyNewForNameOwner(bus,
                                                  kSessionManagerService,
                                                  kSessionManagerPath,
                                                  kSessionManagerInterface,
                                                  &error);
  if (!proxy) {
    LOG(ERROR) << "Error getting FlimFlam proxy: "
               << utils::GetAndFreeGError(&error);
  }
  return proxy;
}

namespace {
enum ProxyMode {
  kProxyModeDirect = 0,
  kProxyModeAutoDetect,
  kProxyModePACScript,
  kProxyModeSingle,
  kProxyModeProxyPerScheme
};
}  // namespace {}

bool ChromeProxyResolver::GetProxiesForUrlWithSettings(
    const string& url,
    const string& json_settings,
    std::deque<std::string>* out_proxies) {
  base::JSONReader parser;

  scoped_ptr<Value> root(
      parser.JsonToValue(json_settings,
                         true,  // check root is obj/arr
                         false));  // false = disallow trailing comma
  if (!root.get()) {
    LOG(ERROR) << "Unable to parse \"" << json_settings << "\": "
               << parser.GetErrorMessage();
    return false;
  }

  TEST_AND_RETURN_FALSE(root->IsType(Value::TYPE_DICTIONARY));

  DictionaryValue* root_dict = dynamic_cast<DictionaryValue*>(root.get());
  TEST_AND_RETURN_FALSE(root_dict);
  int mode = -1;
  TEST_AND_RETURN_FALSE(root_dict->GetInteger("mode", &mode));

  LOG(INFO) << "proxy mode: " << mode;
  if (mode != kProxyModeSingle &&
      mode != kProxyModeProxyPerScheme) {
    LOG(INFO) << "unsupported proxy scheme";
    out_proxies->clear();
    out_proxies->push_back(kNoProxy);
    return true;
  }
  if (mode == kProxyModeSingle) {
    LOG(INFO) << "single proxy mode";
    string proxy_string;
    TEST_AND_RETURN_FALSE(root_dict->GetString("single.server", &proxy_string));
    if (proxy_string.find("://") == string::npos) {
      // missing protocol, assume http.
      proxy_string = string("http://") + proxy_string;
    }
    out_proxies->clear();
    out_proxies->push_back(proxy_string);
    LOG(INFO) << "single proxy: " << (*out_proxies)[0];
    out_proxies->push_back(kNoProxy);
    return true;
  }
  // Proxy per scheme mode.
  LOG(INFO) << "proxy per scheme mode";

  // Find which scheme we are
  bool url_is_http = utils::StringHasPrefix(url, "http://");
  if (!url_is_http)
    TEST_AND_RETURN_FALSE(utils::StringHasPrefix(url, "https://"));

  // Using "proto_*" variables to refer to http or https
  const string proto_path = url_is_http ? "http.server" : "https.server";
  const string socks_path = "socks.server";

  out_proxies->clear();

  string proto_server, socks_server;
  if (root_dict->GetString(proto_path, &proto_server)) {
    if (proto_server.find("://") == string::npos) {
      // missing protocol, assume http.
      proto_server = string("http://") + proto_server;
    }
    out_proxies->push_back(proto_server);
    LOG(INFO) << "got http/https server: " << proto_server;
  }
  if (root_dict->GetString(socks_path, &socks_server)) {
    out_proxies->push_back(socks_server);
    LOG(INFO) << "got socks server: " << proto_server;
  }
  out_proxies->push_back(kNoProxy);
  return true;
}

bool ChromeProxyResolver::GetProxyType(const std::string& proxy,
                                       curl_proxytype* out_type) {
  if (utils::StringHasPrefix(proxy, "socks5://") ||
      utils::StringHasPrefix(proxy, "socks://")) {
    *out_type = CURLPROXY_SOCKS5_HOSTNAME;
    return true;
  }
  if (utils::StringHasPrefix(proxy, "socks4://")) {
    *out_type = CURLPROXY_SOCKS4A;
    return true;
  }
  if (utils::StringHasPrefix(proxy, "http://") ||
      utils::StringHasPrefix(proxy, "https://")) {
    *out_type = CURLPROXY_HTTP;
    return true;
  }
  if (utils::StringHasPrefix(proxy, kNoProxy)) {
    // known failure case. don't log.
    return false;
  }
  LOG(INFO) << "Unknown proxy type: " << proxy;
  return false;
}

}  // namespace chromeos_update_engine
