/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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.
 */

#include <sysexits.h>
#include <unistd.h>  // for isatty()

#include <string>
#include <vector>

#include <base/cancelable_callback.h>
#include <base/command_line.h>
#include <base/files/file_util.h>
#include <base/memory/weak_ptr.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 <chromeos/daemons/dbus_daemon.h>
#include <chromeos/syslog_logging.h>

#include "libcrosservice/dbus-proxies.h"

using std::unique_ptr;

namespace {

const char kLibCrosProxyResolvedSignalInterface[] =
    "org.chromium.CrashReporterLibcrosProxyResolvedInterface";
const char kLibCrosProxyResolvedName[] = "ProxyResolved";
const char kLibCrosServiceName[] = "org.chromium.LibCrosService";
const char kNoProxy[] = "direct://";

const int kTimeoutDefaultSeconds = 5;

const char kHelp[] = "help";
const char kQuiet[] = "quiet";
const char kTimeout[] = "timeout";
const char kVerbose[] = "verbose";
// Help message to show when the --help command line switch is specified.
const char kHelpMessage[] =
    "Chromium OS Crash helper: proxy lister\n"
    "\n"
    "Available Switches:\n"
    "  --quiet      Only print the proxies\n"
    "  --verbose    Print additional messages even when not run from a TTY\n"
    "  --timeout=N  Set timeout for browser resolving proxies (default is 5)\n"
    "  --help       Show this help.\n";

// Copied from src/update_engine/chrome_browser_proxy_resolver.cc
// Parses the browser's answer for resolved proxies.  It returns a
// list of strings, each of which is a resolved proxy.
std::vector<std::string> ParseProxyString(const std::string& input) {
  std::vector<std::string> ret;
  // Some of this code taken from
  // http://src.chromium.org/svn/trunk/src/net/proxy/proxy_server.cc and
  // http://src.chromium.org/svn/trunk/src/net/proxy/proxy_list.cc
  base::StringTokenizer entry_tok(input, ";");
  while (entry_tok.GetNext()) {
    std::string token = entry_tok.token();
    base::TrimWhitespaceASCII(token, base::TRIM_ALL, &token);

    // Start by finding the first space (if any).
    std::string::iterator space;
    for (space = token.begin(); space != token.end(); ++space) {
      if (IsAsciiWhitespace(*space)) {
        break;
      }
    }

    std::string scheme = std::string(token.begin(), space);
    base::StringToLowerASCII(&scheme);
    // Chrome uses "socks" to mean socks4 and "proxy" to mean http.
    if (scheme == "socks")
      scheme += "4";
    else if (scheme == "proxy")
      scheme = "http";
    else if (scheme != "https" &&
             scheme != "socks4" &&
             scheme != "socks5" &&
             scheme != "direct")
      continue;  // Invalid proxy scheme

    std::string host_and_port = std::string(space, token.end());
    base::TrimWhitespaceASCII(host_and_port, base::TRIM_ALL, &host_and_port);
    if (scheme != "direct" && host_and_port.empty())
      continue;  // Must supply host/port when non-direct proxy used.
    ret.push_back(scheme + "://" + host_and_port);
  }
  if (ret.empty() || *ret.rbegin() != kNoProxy)
    ret.push_back(kNoProxy);
  return ret;
}

// A class for interfacing with Chrome to resolve proxies for a given source
// url.  The class is initialized with the given source url to check, the
// signal interface and name that Chrome will reply to, and how long to wait
// for the resolve request to timeout.  Once initialized, the Run() function
// must be called, which blocks on the D-Bus call to Chrome.  The call returns
// after either the timeout or the proxy has been resolved.  The resolved
// proxies can then be accessed through the proxies() function.
class ProxyResolver : public chromeos::DBusDaemon {
 public:
  ProxyResolver(const std::string& source_url,
                const std::string& signal_interface,
                const std::string& signal_name,
                base::TimeDelta timeout)
      : source_url_(source_url),
        signal_interface_(signal_interface),
        signal_name_(signal_name),
        timeout_(timeout),
        weak_ptr_factory_(this),
        timeout_callback_(base::Bind(&ProxyResolver::HandleBrowserTimeout,
                                     weak_ptr_factory_.GetWeakPtr())) {}

  ~ProxyResolver() override {}

  const std::vector<std::string>& proxies() {
    return proxies_;
  }

  int Run() override {
    // Add task for if the browser proxy call times out.
    base::MessageLoop::current()->PostDelayedTask(
        FROM_HERE,
        timeout_callback_.callback(),
        timeout_);

    return chromeos::DBusDaemon::Run();
  }

 protected:
  // If the browser times out, quit the run loop.
  void HandleBrowserTimeout() {
    LOG(ERROR) << "Timeout while waiting for browser to resolve proxy";
    Quit();
  }

  // If the signal handler connects successfully, call the browser's
  // ResolveNetworkProxy D-Bus method.  Otherwise, don't do anything and let
  // the timeout task quit the run loop.
  void HandleDBusSignalConnected(const std::string& interface,
                                 const std::string& signal,
                                 bool success) {
    if (!success) {
      LOG(ERROR) << "Could not connect to signal " << interface << "."
                 << signal;
      timeout_callback_.Cancel();
      Quit();
      return;
    }

    chromeos::ErrorPtr error;
    call_proxy_->ResolveNetworkProxy(source_url_,
                                     signal_interface_,
                                     signal_name_,
                                     &error);

    if (error) {
      LOG(ERROR) << "Call to ResolveNetworkProxy failed: "
                 << error->GetMessage();
      timeout_callback_.Cancel();
      Quit();
    }
  }

  // Handle incoming ProxyResolved signal.
  void HandleProxyResolvedSignal(const std::string& source_url,
                                 const std::string& proxy_info,
                                 const std::string& error_message) {
    timeout_callback_.Cancel();
    proxies_ = ParseProxyString(proxy_info);
    LOG(INFO) << "Found proxies via browser signal: "
              << JoinString(proxies_, 'x');

    Quit();
  }

  int OnInit() override {
    int return_code = chromeos::DBusDaemon::OnInit();
    if (return_code != EX_OK)
      return return_code;

    // Initialize D-Bus proxies.
    call_proxy_.reset(
        new org::chromium::LibCrosServiceInterfaceProxy(bus_,
                                                        kLibCrosServiceName));
    signal_proxy_.reset(
        new org::chromium::CrashReporterLibcrosProxyResolvedInterfaceProxy(
            bus_,
            kLibCrosServiceName));

    // Set up the D-Bus signal handler.
    // TODO(crbug.com/446115): Update ResolveNetworkProxy call to use an
    //     asynchronous return value rather than a return signal.
    signal_proxy_->RegisterProxyResolvedSignalHandler(
        base::Bind(&ProxyResolver::HandleProxyResolvedSignal,
                   weak_ptr_factory_.GetWeakPtr()),
        base::Bind(&ProxyResolver::HandleDBusSignalConnected,
                   weak_ptr_factory_.GetWeakPtr()));

    return EX_OK;
  }

 private:
  unique_ptr<org::chromium::LibCrosServiceInterfaceProxy> call_proxy_;
  unique_ptr<org::chromium::CrashReporterLibcrosProxyResolvedInterfaceProxy>
      signal_proxy_;

  const std::string source_url_;
  const std::string signal_interface_;
  const std::string signal_name_;
  base::TimeDelta timeout_;

  std::vector<std::string> proxies_;
  base::WeakPtrFactory<ProxyResolver> weak_ptr_factory_;

  base::CancelableClosure timeout_callback_;

  DISALLOW_COPY_AND_ASSIGN(ProxyResolver);
};

static bool ShowBrowserProxies(std::string url, base::TimeDelta timeout) {
  // Initialize and run the proxy resolver to watch for signals.
  ProxyResolver resolver(url,
                         kLibCrosProxyResolvedSignalInterface,
                         kLibCrosProxyResolvedName,
                         timeout);
  resolver.Run();

  std::vector<std::string> proxies = resolver.proxies();

  // If proxies is empty, then the timeout was reached waiting for the proxy
  // resolved signal.  If no proxies are defined, proxies will be populated
  // with "direct://".
  if (proxies.empty())
    return false;

  for (const auto& proxy : proxies) {
    printf("%s\n", proxy.c_str());
  }
  return true;
}

}  // namespace

int main(int argc, char *argv[]) {
  base::CommandLine::Init(argc, argv);
  base::CommandLine* cl = base::CommandLine::ForCurrentProcess();

  if (cl->HasSwitch(kHelp)) {
    LOG(INFO) << kHelpMessage;
    return 0;
  }

  bool quiet = cl->HasSwitch(kQuiet);
  bool verbose = cl->HasSwitch(kVerbose);

  int timeout = kTimeoutDefaultSeconds;
  std::string str_timeout = cl->GetSwitchValueASCII(kTimeout);
  if (!str_timeout.empty() && !base::StringToInt(str_timeout, &timeout)) {
    LOG(ERROR) << "Invalid timeout value: " << str_timeout;
    return 1;
  }

  // Default to logging to syslog.
  int init_flags = chromeos::kLogToSyslog;
  // Log to stderr if a TTY (and "-quiet" wasn't passed), or if "-verbose"
  // was passed.

  if ((!quiet && isatty(STDERR_FILENO)) || verbose)
    init_flags |= chromeos::kLogToStderr;
  chromeos::InitLog(init_flags);

  std::string url;
  base::CommandLine::StringVector urls = cl->GetArgs();
  if (!urls.empty()) {
    url = urls[0];
    LOG(INFO) << "Resolving proxies for URL: " << url;
  } else {
    LOG(INFO) << "Resolving proxies without URL";
  }

  if (!ShowBrowserProxies(url, base::TimeDelta::FromSeconds(timeout))) {
    LOG(ERROR) << "Error resolving proxies via the browser";
    LOG(INFO) << "Assuming direct proxy";
    printf("%s\n", kNoProxy);
  }

  return 0;
}
