// Copyright 2018 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_mdns_task.h"

#include <algorithm>
#include <utility>

#include "base/logging.h"
#include "base/strings/string_util.h"
#include "net/base/ip_endpoint.h"
#include "net/base/net_errors.h"
#include "net/dns/public/dns_protocol.h"
#include "net/dns/record_parsed.h"
#include "net/dns/record_rdata.h"

namespace net {

class HostResolverMdnsTask::Transaction {
 public:
  Transaction(DnsQueryType query_type, HostResolverMdnsTask* task)
      : query_type_(query_type),
        results_(ERR_IO_PENDING, HostCache::Entry::SOURCE_UNKNOWN),
        task_(task) {}

  void Start() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(task_->sequence_checker_);

    // Should not be completed or running yet.
    DCHECK_EQ(ERR_IO_PENDING, results_.error());
    DCHECK(!async_transaction_);

    // TODO(crbug.com/846423): Use |allow_cached_response| to set the
    // QUERY_CACHE flag or not.
    int flags = MDnsTransaction::SINGLE_RESULT | MDnsTransaction::QUERY_CACHE |
                MDnsTransaction::QUERY_NETWORK;
    // If |this| is destroyed, destruction of |internal_transaction_| should
    // cancel and prevent invocation of OnComplete.
    std::unique_ptr<MDnsTransaction> inner_transaction =
        task_->mdns_client_->CreateTransaction(
            DnsQueryTypeToQtype(query_type_), task_->hostname_, flags,
            base::BindRepeating(&HostResolverMdnsTask::Transaction::OnComplete,
                                base::Unretained(this)));

    // Side effect warning: Start() may finish and invoke callbacks inline.
    bool start_result = inner_transaction->Start();

    if (!start_result)
      task_->Complete(true /* post_needed */);
    else if (results_.error() == ERR_IO_PENDING)
      async_transaction_ = std::move(inner_transaction);
  }

  bool IsDone() const { return results_.error() != ERR_IO_PENDING; }
  bool IsError() const {
    return IsDone() && results_.error() != OK &&
           results_.error() != ERR_NAME_NOT_RESOLVED;
  }
  const HostCache::Entry& results() const { return results_; }

  void Cancel() {
    DCHECK_CALLED_ON_VALID_SEQUENCE(task_->sequence_checker_);
    DCHECK_EQ(ERR_IO_PENDING, results_.error());

    results_ = HostCache::Entry(ERR_FAILED, HostCache::Entry::SOURCE_UNKNOWN);
    async_transaction_ = nullptr;
  }

 private:
  void OnComplete(MDnsTransaction::Result result, const RecordParsed* parsed) {
    DCHECK_CALLED_ON_VALID_SEQUENCE(task_->sequence_checker_);
    DCHECK_EQ(ERR_IO_PENDING, results_.error());

    int error = ERR_UNEXPECTED;
    switch (result) {
      case MDnsTransaction::RESULT_RECORD:
        error = OK;
        break;
      case MDnsTransaction::RESULT_NO_RESULTS:
      case MDnsTransaction::RESULT_NSEC:
        error = ERR_NAME_NOT_RESOLVED;
        break;
      default:
        // No other results should be possible with the request flags used.
        NOTREACHED();
    }

    if (error == net::OK) {
      // Expected to be validated by MDnsClient.
      DCHECK_EQ(DnsQueryTypeToQtype(query_type_), parsed->type());
      DCHECK(
          base::EqualsCaseInsensitiveASCII(task_->hostname_, parsed->name()));

      switch (query_type_) {
        case DnsQueryType::UNSPECIFIED:
          // Should create two separate transactions with specified type.
          NOTREACHED();
          break;
        case DnsQueryType::A:
          results_ = HostCache::Entry(
              OK,
              AddressList(
                  IPEndPoint(parsed->rdata<net::ARecordRdata>()->address(), 0)),
              HostCache::Entry::SOURCE_UNKNOWN);
          break;
        case DnsQueryType::AAAA:
          results_ = HostCache::Entry(
              OK,
              AddressList(IPEndPoint(
                  parsed->rdata<net::AAAARecordRdata>()->address(), 0)),
              HostCache::Entry::SOURCE_UNKNOWN);
          break;
        case DnsQueryType::TXT:
          results_ = HostCache::Entry(
              OK, parsed->rdata<net::TxtRecordRdata>()->texts(),
              HostCache::Entry::SOURCE_UNKNOWN);
          break;
      }
    } else {
      results_ = HostCache::Entry(error, HostCache::Entry::SOURCE_UNKNOWN);
    }

    // If we don't have a saved async_transaction, it means OnComplete was
    // invoked inline in MDnsTransaction::Start. Callbacks will need to be
    // invoked via post.
    task_->CheckCompletion(!async_transaction_);
  }

  const DnsQueryType query_type_;

  // ERR_IO_PENDING until transaction completes (or is cancelled).
  HostCache::Entry results_;

  // Not saved until MDnsTransaction::Start completes to differentiate inline
  // completion.
  std::unique_ptr<MDnsTransaction> async_transaction_;

  // Back pointer. Expected to destroy |this| before destroying itself.
  HostResolverMdnsTask* const task_;
};

HostResolverMdnsTask::HostResolverMdnsTask(
    MDnsClient* mdns_client,
    const std::string& hostname,
    const std::vector<DnsQueryType>& query_types)
    : mdns_client_(mdns_client), hostname_(hostname), weak_ptr_factory_(this) {
  DCHECK(!query_types.empty());
  for (DnsQueryType query_type : query_types) {
    transactions_.emplace_back(query_type, this);
  }
}

HostResolverMdnsTask::~HostResolverMdnsTask() {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  transactions_.clear();
}

void HostResolverMdnsTask::Start(base::OnceClosure completion_closure) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!completion_closure_);

  completion_closure_ = std::move(completion_closure);

  for (auto& transaction : transactions_) {
    // Only start transaction if it is not already marked done. A transaction
    // could be marked done before starting if it is preemptively canceled by
    // a previously started transaction finishing with an error.
    if (!transaction.IsDone())
      transaction.Start();
  }
}

HostCache::Entry HostResolverMdnsTask::GetResults() const {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
  DCHECK(!transactions_.empty());
  DCHECK(!completion_closure_);
  DCHECK(std::all_of(transactions_.begin(), transactions_.end(),
                     [](const Transaction& t) { return t.IsDone(); }));

  auto found_error =
      std::find_if(transactions_.begin(), transactions_.end(),
                   [](const Transaction& t) { return t.IsError(); });
  if (found_error != transactions_.end()) {
    return found_error->results();
  }

  HostCache::Entry combined_results = transactions_.front().results();
  for (auto it = ++transactions_.begin(); it != transactions_.end(); ++it) {
    combined_results = HostCache::Entry::MergeEntries(
        std::move(combined_results), it->results());
  }

  return combined_results;
}

void HostResolverMdnsTask::CheckCompletion(bool post_needed) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Finish immediately if any transactions completed with an error.
  if (std::any_of(transactions_.begin(), transactions_.end(),
                  [](const Transaction& t) { return t.IsError(); })) {
    Complete(post_needed);
    return;
  }

  if (std::all_of(transactions_.begin(), transactions_.end(),
                  [](const Transaction& t) { return t.IsDone(); })) {
    Complete(post_needed);
    return;
  }
}

void HostResolverMdnsTask::Complete(bool post_needed) {
  DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);

  // Cancel any incomplete async transactions.
  for (auto& transaction : transactions_) {
    if (!transaction.IsDone())
      transaction.Cancel();
  }

  if (post_needed) {
    base::SequencedTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, base::BindOnce(
                       [](base::WeakPtr<HostResolverMdnsTask> task) {
                         if (task)
                           std::move(task->completion_closure_).Run();
                       },
                       weak_ptr_factory_.GetWeakPtr()));
  } else {
    std::move(completion_closure_).Run();
  }
}

}  // namespace net
