// 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 "net/dns/host_resolver_mojo.h"

#include <memory>
#include <utility>

#include "base/callback_helpers.h"
#include "mojo/public/cpp/bindings/binding.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"

namespace net {
namespace {

// Default TTL for successful host resolutions.
const int kCacheEntryTTLSeconds = 5;

// Default TTL for unsuccessful host resolutions.
const int kNegativeCacheEntryTTLSeconds = 0;

HostCache::Key CacheKeyForRequest(const HostResolver::RequestInfo& info) {
  return HostCache::Key(info.hostname(), info.address_family(),
                        info.host_resolver_flags());
}

}  // namespace

class HostResolverMojo::Job : public interfaces::HostResolverRequestClient {
 public:
  Job(const HostCache::Key& key,
      AddressList* addresses,
      const CompletionCallback& callback,
      mojo::InterfaceRequest<interfaces::HostResolverRequestClient> request,
      base::WeakPtr<HostCache> host_cache);

 private:
  // interfaces::HostResolverRequestClient override.
  void ReportResult(int32_t error, const AddressList& address_list) override;

  // Mojo error handler.
  void OnConnectionError();

  const HostCache::Key key_;
  AddressList* addresses_;
  CompletionCallback callback_;
  mojo::Binding<interfaces::HostResolverRequestClient> binding_;
  base::WeakPtr<HostCache> host_cache_;
};

class HostResolverMojo::RequestImpl : public HostResolver::Request {
 public:
  explicit RequestImpl(std::unique_ptr<Job> job) : job_(std::move(job)) {}

  ~RequestImpl() override {}

  void ChangeRequestPriority(RequestPriority priority) override {}

 private:
  std::unique_ptr<Job> job_;
};

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

HostResolverMojo::~HostResolverMojo() = default;

int HostResolverMojo::Resolve(const RequestInfo& info,
                              RequestPriority priority,
                              AddressList* addresses,
                              const CompletionCallback& callback,
                              std::unique_ptr<Request>* request,
                              const NetLogWithSource& source_net_log) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DCHECK(request);
  DVLOG(1) << "Resolve " << info.host_port_pair().ToString();

  HostCache::Key key = CacheKeyForRequest(info);
  int cached_result = ResolveFromCacheInternal(info, key, addresses);
  if (cached_result != ERR_DNS_CACHE_MISS) {
    DVLOG(1) << "Resolved " << info.host_port_pair().ToString()
             << " from cache";
    return cached_result;
  }

  interfaces::HostResolverRequestClientPtr handle;
  std::unique_ptr<Job> job(new Job(key, addresses, callback,
                                   mojo::MakeRequest(&handle),
                                   host_cache_weak_factory_.GetWeakPtr()));
  request->reset(new RequestImpl(std::move(job)));

  impl_->ResolveDns(std::make_unique<HostResolver::RequestInfo>(info),
                    std::move(handle));
  return ERR_IO_PENDING;
}

int HostResolverMojo::ResolveFromCache(const RequestInfo& info,
                                       AddressList* addresses,
                                       const NetLogWithSource& source_net_log) {
  DCHECK(thread_checker_.CalledOnValidThread());
  DVLOG(1) << "ResolveFromCache " << info.host_port_pair().ToString();
  return ResolveFromCacheInternal(info, CacheKeyForRequest(info), addresses);
}

HostCache* HostResolverMojo::GetHostCache() {
  return host_cache_.get();
}

int HostResolverMojo::ResolveFromCacheInternal(const RequestInfo& info,
                                               const HostCache::Key& key,
                                               AddressList* addresses) {
  if (!info.allow_cached_response())
    return ERR_DNS_CACHE_MISS;

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

  *addresses = AddressList::CopyWithPort(entry->addresses(), info.port());
  return entry->error();
}

HostResolverMojo::Job::Job(
    const HostCache::Key& key,
    AddressList* addresses,
    const CompletionCallback& callback,
    mojo::InterfaceRequest<interfaces::HostResolverRequestClient> request,
    base::WeakPtr<HostCache> host_cache)
    : key_(key),
      addresses_(addresses),
      callback_(callback),
      binding_(this, std::move(request)),
      host_cache_(host_cache) {
  binding_.set_connection_error_handler(base::Bind(
      &HostResolverMojo::Job::OnConnectionError, base::Unretained(this)));
}

void HostResolverMojo::Job::ReportResult(int32_t error,
                                         const AddressList& address_list) {
  if (error == OK)
    *addresses_ = address_list;
  if (host_cache_) {
    base::TimeDelta ttl = base::TimeDelta::FromSeconds(
        error == OK ? kCacheEntryTTLSeconds : kNegativeCacheEntryTTLSeconds);
    HostCache::Entry entry(error, *addresses_, ttl);
    host_cache_->Set(key_, entry, base::TimeTicks::Now(), ttl);
  }
  if (binding_.is_bound())
    binding_.Close();
  base::ResetAndReturn(&callback_).Run(error);
}

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

}  // namespace net
