// Copyright 2015 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 "services/proxy_resolver/host_resolver_mojo.h"

#include <memory>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/callback_helpers.h"
#include "base/time/time.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/address_family.h"
#include "net/base/address_list.h"
#include "net/base/completion_once_callback.h"
#include "net/base/ip_address.h"
#include "net/base/net_errors.h"

namespace proxy_resolver {
namespace {

// Default TTL for successful host resolutions.
constexpr auto kCacheEntryTTL = base::TimeDelta::FromSeconds(5);

// Default TTL for unsuccessful host resolutions.
constexpr auto kNegativeCacheEntryTTL = base::TimeDelta();

net::HostCache::Key CacheKeyForRequest(
    const std::string& hostname,
    net::ProxyResolverV8::JSBindings::ResolveDnsOperation operation) {
  net::AddressFamily address_family = net::ADDRESS_FAMILY_UNSPECIFIED;
  if (operation == net::ProxyResolverV8::JSBindings::MY_IP_ADDRESS ||
      operation == net::ProxyResolverV8::JSBindings::DNS_RESOLVE) {
    address_family = net::ADDRESS_FAMILY_IPV4;
  }

  return net::HostCache::Key(hostname, address_family,
                             0 /* host_resolver_flags */);
}

}  // namespace

class HostResolverMojo::RequestImpl : public ProxyHostResolver::Request,
                                      public mojom::HostResolverRequestClient {
 public:
  RequestImpl(const std::string& hostname,
              net::ProxyResolverV8::JSBindings::ResolveDnsOperation operation,
              base::WeakPtr<net::HostCache> host_cache,
              Impl* impl)
      : hostname_(hostname),
        operation_(operation),
        binding_(this),
        host_cache_(std::move(host_cache)),
        impl_(impl) {}

  ~RequestImpl() override = default;

  // ProxyHostResolver::Request override
  int Start(net::CompletionOnceCallback callback) override {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
    DVLOG(1) << "Resolve " << hostname_;

    int cached_result = ResolveFromCacheInternal();
    if (cached_result != net::ERR_DNS_CACHE_MISS) {
      DVLOG(1) << "Resolved " << hostname_ << " from cache";
      return cached_result;
    }

    callback_ = std::move(callback);

    mojom::HostResolverRequestClientPtr handle;
    binding_.Bind(mojo::MakeRequest(&handle));
    binding_.set_connection_error_handler(base::BindOnce(
        &RequestImpl::OnConnectionError, base::Unretained(this)));

    impl_->ResolveDns(hostname_, operation_, std::move(handle));
    return net::ERR_IO_PENDING;
  }

  const std::vector<net::IPAddress>& GetResults() const override {
    return results_;
  }

  // mojom::HostResolverRequestClient override
  void ReportResult(int32_t error,
                    const net::AddressList& address_list) override {
    DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);

    if (error == net::OK)
      results_ = AddressListToAddresses(address_list);
    if (host_cache_) {
      base::TimeDelta ttl =
          error == net::OK ? kCacheEntryTTL : kNegativeCacheEntryTTL;
      net::HostCache::Entry entry(error, address_list,
                                  net::HostCache::Entry::SOURCE_UNKNOWN, ttl);
      host_cache_->Set(CacheKeyForRequest(hostname_, operation_), entry,
                       base::TimeTicks::Now(), ttl);
    }
    if (binding_.is_bound())
      binding_.Close();
    std::move(callback_).Run(error);
  }

 private:
  int ResolveFromCacheInternal() {
    DCHECK(host_cache_);

    net::HostCache::Key key = CacheKeyForRequest(hostname_, operation_);
    const net::HostCache::Entry* entry =
        host_cache_->Lookup(key, base::TimeTicks::Now());
    if (!entry)
      return net::ERR_DNS_CACHE_MISS;

    results_ = AddressListToAddresses(entry->addresses().value());
    return entry->error();
  }

  void OnConnectionError() {
    ReportResult(net::ERR_FAILED, net::AddressList());
  }

  static std::vector<net::IPAddress> AddressListToAddresses(
      net::AddressList address_list) {
    std::vector<net::IPAddress> result;
    for (net::IPEndPoint endpoint : address_list.endpoints()) {
      result.push_back(endpoint.address());
    }
    return result;
  }

  const std::string hostname_;
  const net::ProxyResolverV8::JSBindings::ResolveDnsOperation operation_;

  mojo::Binding<mojom::HostResolverRequestClient> binding_;
  net::CompletionOnceCallback callback_;

  base::WeakPtr<net::HostCache> host_cache_;
  Impl* const impl_;
  std::vector<net::IPAddress> results_;

  THREAD_CHECKER(thread_checker_);
};

HostResolverMojo::HostResolverMojo(Impl* impl)
    : impl_(impl),
      host_cache_(net::HostCache::CreateDefaultCache()),
      host_cache_weak_factory_(host_cache_.get()) {}

HostResolverMojo::~HostResolverMojo() = default;

std::unique_ptr<net::ProxyHostResolver::Request>
HostResolverMojo::CreateRequest(
    const std::string& hostname,
    net::ProxyResolverV8::JSBindings::ResolveDnsOperation operation) {
  DCHECK(thread_checker_.CalledOnValidThread());
  return std::make_unique<RequestImpl>(
      hostname, operation, host_cache_weak_factory_.GetWeakPtr(), impl_);
}

}  // namespace proxy_resolver
