// 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/base/mock_host_resolver.h"

#include "base/memory/ref_counted.h"
#include "base/string_split.h"
#include "base/string_util.h"
#include "base/threading/platform_thread.h"
#include "net/base/net_errors.h"
#include "net/base/net_util.h"
#include "net/base/sys_addrinfo.h"

namespace net {

namespace {

char* do_strdup(const char* src) {
#if defined(OS_WIN)
  return _strdup(src);
#else
  return strdup(src);
#endif
}

// Fills |*addrlist| with a socket address for |host_list| which should be a
// comma-separated list of IPv4 or IPv6 literal(s) without enclosing brackets.
// If |canonical_name| is non-empty it is used as the DNS canonical name for
// the host. Returns OK on success, ERR_UNEXPECTED otherwise.
int CreateIPAddressList(const std::string& host_list,
                        const std::string& canonical_name,
                        AddressList* addrlist) {
  *addrlist = AddressList();
  std::vector<std::string> addresses;
  base::SplitString(host_list, ',', &addresses);
  for (size_t index = 0; index < addresses.size(); ++index) {
    IPAddressNumber ip_number;
    if (!ParseIPLiteralToNumber(addresses[index], &ip_number)) {
      LOG(WARNING) << "Not a supported IP literal: " << addresses[index];
      return ERR_UNEXPECTED;
    }

    AddressList result(ip_number, -1, false);
    struct addrinfo* ai = const_cast<struct addrinfo*>(result.head());
    if (index == 0)
      ai->ai_canonname = do_strdup(canonical_name.c_str());
    if (!addrlist->head())
      addrlist->Copy(result.head(), false);
    else
      addrlist->Append(result.head());
  }
  return OK;
}

}  // namespace

MockHostResolverBase::~MockHostResolverBase() {}

void MockHostResolverBase::Reset(HostResolverProc* interceptor) {
  synchronous_mode_ = false;

  // At the root of the chain, map everything to localhost.
  scoped_refptr<RuleBasedHostResolverProc> catchall(
      new RuleBasedHostResolverProc(NULL));
  catchall->AddRule("*", "127.0.0.1");

  // Next add a rules-based layer the use controls.
  rules_ = new RuleBasedHostResolverProc(catchall);

  HostResolverProc* proc = rules_;

  // Lastly add the provided interceptor to the front of the chain.
  if (interceptor) {
    interceptor->SetPreviousProc(proc);
    proc = interceptor;
  }

  HostCache* cache = NULL;

  if (use_caching_) {
    cache = new HostCache(
        100,  // max entries.
        base::TimeDelta::FromMinutes(1),
        base::TimeDelta::FromSeconds(0));
  }

  impl_.reset(new HostResolverImpl(proc, cache, 50u, NULL));
}

int MockHostResolverBase::Resolve(const RequestInfo& info,
                                  AddressList* addresses,
                                  CompletionCallback* callback,
                                  RequestHandle* out_req,
                                  const BoundNetLog& net_log) {
  if (synchronous_mode_) {
    callback = NULL;
    out_req = NULL;
  }
  return impl_->Resolve(info, addresses, callback, out_req, net_log);
}

void MockHostResolverBase::CancelRequest(RequestHandle req) {
  impl_->CancelRequest(req);
}

void MockHostResolverBase::AddObserver(Observer* observer) {
  impl_->AddObserver(observer);
}

void MockHostResolverBase::RemoveObserver(Observer* observer) {
  impl_->RemoveObserver(observer);
}

MockHostResolverBase::MockHostResolverBase(bool use_caching)
    : use_caching_(use_caching) {
  Reset(NULL);
}

//-----------------------------------------------------------------------------

struct RuleBasedHostResolverProc::Rule {
  enum ResolverType {
    kResolverTypeFail,
    kResolverTypeSystem,
    kResolverTypeIPLiteral,
  };

  ResolverType resolver_type;
  std::string host_pattern;
  AddressFamily address_family;
  HostResolverFlags host_resolver_flags;
  std::string replacement;
  std::string canonical_name;
  int latency_ms;  // In milliseconds.

  Rule(ResolverType resolver_type,
       const std::string& host_pattern,
       AddressFamily address_family,
       HostResolverFlags host_resolver_flags,
       const std::string& replacement,
       const std::string& canonical_name,
       int latency_ms)
      : resolver_type(resolver_type),
        host_pattern(host_pattern),
        address_family(address_family),
        host_resolver_flags(host_resolver_flags),
        replacement(replacement),
        canonical_name(canonical_name),
        latency_ms(latency_ms) {}
};

RuleBasedHostResolverProc::RuleBasedHostResolverProc(HostResolverProc* previous)
    : HostResolverProc(previous) {
}

void RuleBasedHostResolverProc::AddRule(const std::string& host_pattern,
                                        const std::string& replacement) {
  AddRuleForAddressFamily(host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
                          replacement);
}

void RuleBasedHostResolverProc::AddRuleForAddressFamily(
    const std::string& host_pattern,
    AddressFamily address_family,
    const std::string& replacement) {
  DCHECK(!replacement.empty());
  HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
      HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
  Rule rule(Rule::kResolverTypeSystem, host_pattern, address_family, flags,
            replacement, "", 0);
  rules_.push_back(rule);
}

void RuleBasedHostResolverProc::AddIPLiteralRule(
    const std::string& host_pattern,
    const std::string& ip_literal,
    const std::string& canonical_name) {
  // Literals are always resolved to themselves by HostResolverImpl,
  // consequently we do not support remapping them.
  IPAddressNumber ip_number;
  DCHECK(!ParseIPLiteralToNumber(host_pattern, &ip_number));
  HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
      HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
  if (!canonical_name.empty())
    flags |= HOST_RESOLVER_CANONNAME;
  Rule rule(Rule::kResolverTypeIPLiteral, host_pattern,
            ADDRESS_FAMILY_UNSPECIFIED, flags, ip_literal, canonical_name,
            0);
  rules_.push_back(rule);
}

void RuleBasedHostResolverProc::AddRuleWithLatency(
    const std::string& host_pattern,
    const std::string& replacement,
    int latency_ms) {
  DCHECK(!replacement.empty());
  HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
      HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
  Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
            flags, replacement, "", latency_ms);
  rules_.push_back(rule);
}

void RuleBasedHostResolverProc::AllowDirectLookup(
    const std::string& host_pattern) {
  HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
      HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
  Rule rule(Rule::kResolverTypeSystem, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
            flags, "", "", 0);
  rules_.push_back(rule);
}

void RuleBasedHostResolverProc::AddSimulatedFailure(
    const std::string& host_pattern) {
  HostResolverFlags flags = HOST_RESOLVER_LOOPBACK_ONLY |
      HOST_RESOLVER_DEFAULT_FAMILY_SET_DUE_TO_NO_IPV6;
  Rule rule(Rule::kResolverTypeFail, host_pattern, ADDRESS_FAMILY_UNSPECIFIED,
            flags, "", "", 0);
  rules_.push_back(rule);
}

int RuleBasedHostResolverProc::Resolve(const std::string& host,
                                       AddressFamily address_family,
                                       HostResolverFlags host_resolver_flags,
                                       AddressList* addrlist,
                                       int* os_error) {
  RuleList::iterator r;
  for (r = rules_.begin(); r != rules_.end(); ++r) {
    bool matches_address_family =
        r->address_family == ADDRESS_FAMILY_UNSPECIFIED ||
        r->address_family == address_family;
    // Flags match if all of the bitflags in host_resolver_flags are enabled
    // in the rule's host_resolver_flags. However, the rule may have additional
    // flags specified, in which case the flags should still be considered a
    // match.
    bool matches_flags = (r->host_resolver_flags & host_resolver_flags) ==
        host_resolver_flags;
    if (matches_flags && matches_address_family &&
        MatchPattern(host, r->host_pattern)) {
      if (r->latency_ms != 0)
        base::PlatformThread::Sleep(r->latency_ms);

      // Remap to a new host.
      const std::string& effective_host =
          r->replacement.empty() ? host : r->replacement;

      // Apply the resolving function to the remapped hostname.
      switch (r->resolver_type) {
        case Rule::kResolverTypeFail:
          return ERR_NAME_NOT_RESOLVED;
        case Rule::kResolverTypeSystem:
          return SystemHostResolverProc(effective_host,
                                        address_family,
                                        host_resolver_flags,
                                        addrlist, os_error);
        case Rule::kResolverTypeIPLiteral:
          return CreateIPAddressList(effective_host,
                                     r->canonical_name,
                                     addrlist);
        default:
          NOTREACHED();
          return ERR_UNEXPECTED;
      }
    }
  }
  return ResolveUsingPrevious(host, address_family,
                              host_resolver_flags, addrlist, os_error);
}

RuleBasedHostResolverProc::~RuleBasedHostResolverProc() {
}

//-----------------------------------------------------------------------------

WaitingHostResolverProc::WaitingHostResolverProc(HostResolverProc* previous)
    : HostResolverProc(previous), event_(false, false) {}

void WaitingHostResolverProc::Signal() {
  event_.Signal();
}

int WaitingHostResolverProc::Resolve(const std::string& host,
                                     AddressFamily address_family,
                                     HostResolverFlags host_resolver_flags,
                                     AddressList* addrlist,
                                     int* os_error) {
  event_.Wait();
  return ResolveUsingPrevious(host, address_family, host_resolver_flags,
                              addrlist, os_error);
}

WaitingHostResolverProc::~WaitingHostResolverProc() {}

//-----------------------------------------------------------------------------

ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc() {}

ScopedDefaultHostResolverProc::ScopedDefaultHostResolverProc(
    HostResolverProc* proc) {
  Init(proc);
}

ScopedDefaultHostResolverProc::~ScopedDefaultHostResolverProc() {
  HostResolverProc* old_proc = HostResolverProc::SetDefault(previous_proc_);
  // The lifetimes of multiple instances must be nested.
  CHECK_EQ(old_proc, current_proc_);
}

void ScopedDefaultHostResolverProc::Init(HostResolverProc* proc) {
  current_proc_ = proc;
  previous_proc_ = HostResolverProc::SetDefault(current_proc_);
  current_proc_->SetLastProc(previous_proc_);
}

}  // namespace net
