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

#include "base/basictypes.h"
#include "base/stl_util.h"
#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/dns/host_resolver.h"
#include "net/dns/mojo_type_converters.h"

namespace net {

// Handles host resolution for a single request and sends a response when done.
// Also detects connection errors for HostResolverRequestClient and cancels the
// outstanding resolve request. Owned by MojoHostResolverImpl.
class MojoHostResolverImpl::Job : public mojo::ErrorHandler {
 public:
  Job(MojoHostResolverImpl* resolver_service,
      net::HostResolver* resolver,
      const net::HostResolver::RequestInfo& request_info,
      interfaces::HostResolverRequestClientPtr client);
  ~Job() override;

  void Start();

 private:
  // Completion callback for the HostResolver::Resolve request.
  void OnResolveDone(int result);

  // Overridden from mojo::ErrorHandler:
  void OnConnectionError() override;

  MojoHostResolverImpl* resolver_service_;
  net::HostResolver* resolver_;
  net::HostResolver::RequestInfo request_info_;
  interfaces::HostResolverRequestClientPtr client_;
  net::HostResolver::RequestHandle handle_;
  AddressList result_;
  base::ThreadChecker thread_checker_;
};

MojoHostResolverImpl::MojoHostResolverImpl(net::HostResolver* resolver)
    : resolver_(resolver) {
}

MojoHostResolverImpl::~MojoHostResolverImpl() {
  DCHECK(thread_checker_.CalledOnValidThread());
  STLDeleteElements(&pending_jobs_);
}

void MojoHostResolverImpl::Resolve(
    interfaces::HostResolverRequestInfoPtr request_info,
    interfaces::HostResolverRequestClientPtr client) {
  DCHECK(thread_checker_.CalledOnValidThread());
  Job* job = new Job(this, resolver_,
                     request_info->To<net::HostResolver::RequestInfo>(),
                     client.Pass());
  pending_jobs_.insert(job);
  job->Start();
}

void MojoHostResolverImpl::DeleteJob(Job* job) {
  DCHECK(thread_checker_.CalledOnValidThread());
  size_t num_erased = pending_jobs_.erase(job);
  DCHECK(num_erased);
  delete job;
}

MojoHostResolverImpl::Job::Job(
    MojoHostResolverImpl* resolver_service,
    net::HostResolver* resolver,
    const net::HostResolver::RequestInfo& request_info,
    interfaces::HostResolverRequestClientPtr client)
    : resolver_service_(resolver_service),
      resolver_(resolver),
      request_info_(request_info),
      client_(client.Pass()),
      handle_(nullptr) {
  client_.set_error_handler(this);
}

void MojoHostResolverImpl::Job::Start() {
  DVLOG(1) << "Resolve " << request_info_.host_port_pair().ToString();
  BoundNetLog net_log;
  int result =
      resolver_->Resolve(request_info_, DEFAULT_PRIORITY, &result_,
                         base::Bind(&MojoHostResolverImpl::Job::OnResolveDone,
                                    base::Unretained(this)),
                         &handle_, net_log);

  if (result != ERR_IO_PENDING)
    OnResolveDone(result);
}

MojoHostResolverImpl::Job::~Job() {
  DCHECK(thread_checker_.CalledOnValidThread());
  if (handle_)
    resolver_->CancelRequest(handle_);
}

void MojoHostResolverImpl::Job::OnResolveDone(int result) {
  DCHECK(thread_checker_.CalledOnValidThread());
  handle_ = nullptr;
  DVLOG(1) << "Resolved " << request_info_.host_port_pair().ToString()
           << " with error " << result << " and " << result_.size()
           << " results!";
  for (const auto& address : result_) {
    DVLOG(1) << address.ToString();
  }
  if (result == OK)
    client_->ReportResult(result, interfaces::AddressList::From(result_));
  else
    client_->ReportResult(result, nullptr);

  resolver_service_->DeleteJob(this);
}

void MojoHostResolverImpl::Job::OnConnectionError() {
  DCHECK(thread_checker_.CalledOnValidThread());
  // |resolver_service_| should always outlive us.
  DCHECK(resolver_service_);
  DVLOG(1) << "Connection error on request for "
           << request_info_.host_port_pair().ToString();
  resolver_service_->DeleteJob(this);
}

}  // namespace net
