// Copyright (c) 2011 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 "net/proxy/proxy_resolver_js_bindings.h"

#include "base/compiler_specific.h"
#include "base/logging.h"
#include "base/string_util.h"
#include "base/values.h"
#include "net/base/address_list.h"
#include "net/base/host_cache.h"
#include "net/base/host_resolver.h"
#include "net/base/net_errors.h"
#include "net/base/net_log.h"
#include "net/base/net_util.h"
#include "net/base/sys_addrinfo.h"
#include "net/proxy/proxy_resolver_error_observer.h"
#include "net/proxy/proxy_resolver_request_context.h"
#include "net/proxy/sync_host_resolver.h"

namespace net {

namespace {

// Event parameters for a PAC error message (line number + message).
class ErrorNetlogParams : public NetLog::EventParameters {
 public:
  ErrorNetlogParams(int line_number,
                    const string16& message)
      : line_number_(line_number),
        message_(message) {
  }

  virtual Value* ToValue() const OVERRIDE {
    DictionaryValue* dict = new DictionaryValue();
    dict->SetInteger("line_number", line_number_);
    dict->SetString("message", message_);
    return dict;
  }

 private:
  const int line_number_;
  const string16 message_;

  DISALLOW_COPY_AND_ASSIGN(ErrorNetlogParams);
};

// Event parameters for a PAC alert().
class AlertNetlogParams : public NetLog::EventParameters {
 public:
  explicit AlertNetlogParams(const string16& message) : message_(message) {
  }

  virtual Value* ToValue() const OVERRIDE {
    DictionaryValue* dict = new DictionaryValue();
    dict->SetString("message", message_);
    return dict;
  }

 private:
  const string16 message_;

  DISALLOW_COPY_AND_ASSIGN(AlertNetlogParams);
};

// ProxyResolverJSBindings implementation.
class DefaultJSBindings : public ProxyResolverJSBindings {
 public:
  DefaultJSBindings(SyncHostResolver* host_resolver,
                    NetLog* net_log,
                    ProxyResolverErrorObserver* error_observer)
      : host_resolver_(host_resolver),
        net_log_(net_log),
        error_observer_(error_observer) {
  }

  // Handler for "alert(message)".
  virtual void Alert(const string16& message) OVERRIDE {
    VLOG(1) << "PAC-alert: " << message;

    // Send to the NetLog.
    LogEventToCurrentRequestAndGlobally(NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
                                        new AlertNetlogParams(message));
  }

  // Handler for "myIpAddress()".
  // TODO(eroman): Perhaps enumerate the interfaces directly, using
  // getifaddrs().
  virtual bool MyIpAddress(std::string* first_ip_address) OVERRIDE {
    LogEventToCurrentRequest(NetLog::PHASE_BEGIN,
                             NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS,
                             NULL);

    bool ok = MyIpAddressImpl(first_ip_address);

    LogEventToCurrentRequest(NetLog::PHASE_END,
                             NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS,
                             NULL);
    return ok;
  }

  // Handler for "myIpAddressEx()".
  virtual bool MyIpAddressEx(std::string* ip_address_list) OVERRIDE {
    LogEventToCurrentRequest(NetLog::PHASE_BEGIN,
                             NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS_EX,
                             NULL);

    bool ok = MyIpAddressExImpl(ip_address_list);

    LogEventToCurrentRequest(NetLog::PHASE_END,
                             NetLog::TYPE_PAC_JAVASCRIPT_MY_IP_ADDRESS_EX,
                             NULL);
    return ok;
  }

  // Handler for "dnsResolve(host)".
  virtual bool DnsResolve(const std::string& host,
                          std::string* first_ip_address) OVERRIDE {
    LogEventToCurrentRequest(NetLog::PHASE_BEGIN,
                             NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE,
                             NULL);

    bool ok = DnsResolveImpl(host, first_ip_address);

    LogEventToCurrentRequest(NetLog::PHASE_END,
                             NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE,
                             NULL);
    return ok;
  }

  // Handler for "dnsResolveEx(host)".
  virtual bool DnsResolveEx(const std::string& host,
                            std::string* ip_address_list) OVERRIDE {
    LogEventToCurrentRequest(NetLog::PHASE_BEGIN,
                             NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE_EX,
                             NULL);

    bool ok = DnsResolveExImpl(host, ip_address_list);

    LogEventToCurrentRequest(NetLog::PHASE_END,
                             NetLog::TYPE_PAC_JAVASCRIPT_DNS_RESOLVE_EX,
                             NULL);
    return ok;
  }

  // Handler for when an error is encountered. |line_number| may be -1.
  virtual void OnError(int line_number, const string16& message) OVERRIDE {
    // Send to the chrome log.
    if (line_number == -1)
      VLOG(1) << "PAC-error: " << message;
    else
      VLOG(1) << "PAC-error: " << "line: " << line_number << ": " << message;

    // Send the error to the NetLog.
    LogEventToCurrentRequestAndGlobally(
        NetLog::TYPE_PAC_JAVASCRIPT_ERROR,
        new ErrorNetlogParams(line_number, message));

    if (error_observer_.get())
      error_observer_->OnPACScriptError(line_number, message);
  }

  virtual void Shutdown() OVERRIDE {
    host_resolver_->Shutdown();
  }

 private:
  bool MyIpAddressImpl(std::string* first_ip_address) {
    std::string my_hostname = GetHostName();
    if (my_hostname.empty())
      return false;
    return DnsResolveImpl(my_hostname, first_ip_address);
  }

  bool MyIpAddressExImpl(std::string* ip_address_list) {
    std::string my_hostname = GetHostName();
    if (my_hostname.empty())
      return false;
    return DnsResolveExImpl(my_hostname, ip_address_list);
  }

  bool DnsResolveImpl(const std::string& host,
                      std::string* first_ip_address) {
    // Do a sync resolve of the hostname (port doesn't matter).
    // Disable IPv6 results. We do this because the PAC specification isn't
    // really IPv6 friendly, and Internet Explorer also restricts to IPv4.
    // Consequently a lot of existing PAC scripts assume they will only get
    // IPv4 results, and will misbehave if they get an IPv6 result.
    // See http://crbug.com/24641 for more details.
    HostResolver::RequestInfo info(HostPortPair(host, 80));
    info.set_address_family(ADDRESS_FAMILY_IPV4);
    AddressList address_list;

    int result = DnsResolveHelper(info, &address_list);
    if (result != OK)
      return false;

    // There may be multiple results; we will just use the first one.
    // This returns empty string on failure.
    *first_ip_address = net::NetAddressToString(address_list.head());
    if (first_ip_address->empty())
      return false;

    return true;
  }

  bool DnsResolveExImpl(const std::string& host,
                        std::string* ip_address_list) {
    // Do a sync resolve of the hostname (port doesn't matter).
    HostResolver::RequestInfo info(HostPortPair(host, 80));
    AddressList address_list;
    int result = DnsResolveHelper(info, &address_list);

    if (result != OK)
      return false;

    // Stringify all of the addresses in the address list, separated
    // by semicolons.
    std::string address_list_str;
    const struct addrinfo* current_address = address_list.head();
    while (current_address) {
      if (!address_list_str.empty())
        address_list_str += ";";
      const std::string address_string = NetAddressToString(current_address);
      if (address_string.empty())
        return false;
      address_list_str += address_string;
      current_address = current_address->ai_next;
    }

    *ip_address_list = address_list_str;
    return true;
  }

  // Helper to execute a synchronous DNS resolve, using the per-request
  // DNS cache if there is one.
  int DnsResolveHelper(const HostResolver::RequestInfo& info,
                       AddressList* address_list) {
    HostCache::Key cache_key(info.hostname(),
                             info.address_family(),
                             info.host_resolver_flags());

    HostCache* host_cache = current_request_context() ?
        current_request_context()->host_cache : NULL;

    // First try to service this request from the per-request DNS cache.
    // (we cache DNS failures much more aggressively within the context
    // of a FindProxyForURL() request).
    if (host_cache) {
      const HostCache::Entry* entry =
          host_cache->Lookup(cache_key, base::TimeTicks::Now());
      if (entry) {
        if (entry->error == OK)
          *address_list = entry->addrlist;
        return entry->error;
      }
    }

    // Otherwise ask the host resolver.
    int result = host_resolver_->Resolve(info, address_list);

    // Save the result back to the per-request DNS cache.
    if (host_cache) {
      host_cache->Set(cache_key, result, *address_list,
                      base::TimeTicks::Now());
    }

    return result;
  }

  void LogEventToCurrentRequest(
      NetLog::EventPhase phase,
      NetLog::EventType type,
      scoped_refptr<NetLog::EventParameters> params) {
    if (current_request_context() && current_request_context()->net_log)
      current_request_context()->net_log->AddEntry(type, phase, params);
  }

  void LogEventToCurrentRequestAndGlobally(
      NetLog::EventType type,
      scoped_refptr<NetLog::EventParameters> params) {
    LogEventToCurrentRequest(NetLog::PHASE_NONE, type, params);

    // Emit to the global NetLog event stream.
    if (net_log_) {
      net_log_->AddEntry(
          type,
          base::TimeTicks::Now(),
          NetLog::Source(),
          NetLog::PHASE_NONE,
          params);
    }
  }

  scoped_ptr<SyncHostResolver> host_resolver_;
  NetLog* net_log_;
  scoped_ptr<ProxyResolverErrorObserver> error_observer_;
  DISALLOW_COPY_AND_ASSIGN(DefaultJSBindings);
};

}  // namespace

// static
ProxyResolverJSBindings* ProxyResolverJSBindings::CreateDefault(
    SyncHostResolver* host_resolver,
    NetLog* net_log,
    ProxyResolverErrorObserver* error_observer) {
  return new DefaultJSBindings(host_resolver, net_log, error_observer);
}

}  // namespace net
