// Copyright 2018 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "services/network/resolve_host_request.h"

#include <algorithm>
#include <optional>
#include <string>
#include <utility>

#include "base/check_op.h"
#include "base/containers/to_vector.h"
#include "base/functional/bind.h"
#include "base/strings/string_util.h"
#include "net/base/host_port_pair.h"
#include "net/base/net_errors.h"
#include "net/base/url_util.h"
#include "net/log/net_log.h"
#include "net/log/net_log_with_source.h"
#include "url/url_canon.h"

namespace network {

namespace {

// Attempts URL canonicalization, but if unable, leaves `host_port_pair` alone.
void TryToCanonicalizeHost(net::HostPortPair& host_port_pair) {
  url::CanonHostInfo info;
  std::string canonicalized =
      net::CanonicalizeHost(host_port_pair.host(), &info);
  if (info.family != url::CanonHostInfo::BROKEN) {
    host_port_pair.set_host(canonicalized);
  }
}

}  // namespace

ResolveHostRequest::ResolveHostRequest(
    net::HostResolver* resolver,
    mojom::HostResolverHostPtr host,
    const net::NetworkAnonymizationKey& network_anonymization_key,
    const std::optional<net::HostResolver::ResolveHostParameters>&
        optional_parameters,
    net::NetLog* net_log) {
  DCHECK(resolver);
  DCHECK(net_log);

  if (host->is_host_port_pair()) {
    // net::HostResolver expects canonicalized hostnames.
    net::HostPortPair& host_port_pair = host->get_host_port_pair();
    TryToCanonicalizeHost(host_port_pair);
    internal_request_ = resolver->CreateRequest(
        host_port_pair, network_anonymization_key,
        net::NetLogWithSource::Make(
            net_log, net::NetLogSourceType::NETWORK_SERVICE_HOST_RESOLVER),
        optional_parameters);
  } else {
    internal_request_ = resolver->CreateRequest(
        host->get_scheme_host_port(), network_anonymization_key,
        net::NetLogWithSource::Make(
            net_log, net::NetLogSourceType::NETWORK_SERVICE_HOST_RESOLVER),
        optional_parameters);
  }
}

ResolveHostRequest::~ResolveHostRequest() {
  control_handle_receiver_.reset();

  if (response_client_.is_bound()) {
    response_client_->OnComplete(net::ERR_NAME_NOT_RESOLVED,
                                 net::ResolveErrorInfo(net::ERR_FAILED),
                                 /*resolved_addresses=*/{},
                                 /*alternative_endpoints=*/{});
    response_client_.reset();
  }
}

int ResolveHostRequest::Start(
    mojo::PendingReceiver<mojom::ResolveHostHandle> control_handle_receiver,
    mojo::PendingRemote<mojom::ResolveHostClient> pending_response_client,
    net::CompletionOnceCallback callback) {
  DCHECK(internal_request_);
  DCHECK(!control_handle_receiver_.is_bound());
  DCHECK(!response_client_.is_bound());

  // Unretained |this| reference is safe because if |internal_request_| goes out
  // of scope, it will cancel the request and ResolveHost() will not call the
  // callback.
  int rv = internal_request_->Start(
      base::BindOnce(&ResolveHostRequest::OnComplete, base::Unretained(this)));

  mojo::Remote<mojom::ResolveHostClient> response_client(
      std::move(pending_response_client));
  if (rv != net::ERR_IO_PENDING) {
    response_client->OnComplete(rv, GetResolveErrorInfo(), GetAddressResults(),
                                GetAlternativeEndpoints());
    return rv;
  }

  if (control_handle_receiver)
    control_handle_receiver_.Bind(std::move(control_handle_receiver));

  response_client_ = std::move(response_client);
  // Unretained |this| reference is safe because connection error cannot occur
  // if |response_client_| goes out of scope.
  response_client_.set_disconnect_handler(base::BindOnce(
      &ResolveHostRequest::Cancel, base::Unretained(this), net::ERR_FAILED));

  callback_ = std::move(callback);

  return net::ERR_IO_PENDING;
}

void ResolveHostRequest::Cancel(int error) {
  DCHECK_NE(net::OK, error);

  if (cancelled_)
    return;

  internal_request_ = nullptr;
  cancelled_ = true;
  resolve_error_info_ = net::ResolveErrorInfo(error);
  OnComplete(error);
}

void ResolveHostRequest::OnComplete(int error) {
  DCHECK(response_client_.is_bound());
  DCHECK(callback_);

  control_handle_receiver_.reset();
  SignalNonAddressResults();
  response_client_->OnComplete(error, GetResolveErrorInfo(),
                               GetAddressResults(), GetAlternativeEndpoints());

  response_client_.reset();
  // Invoke completion callback last as it may delete |this|.
  std::move(callback_).Run(GetResolveErrorInfo().error);
}

net::ResolveErrorInfo ResolveHostRequest::GetResolveErrorInfo() const {
  if (cancelled_) {
    return resolve_error_info_;
  }

  DCHECK(internal_request_);
  return internal_request_->GetResolveErrorInfo();
}

net::AddressList ResolveHostRequest::GetAddressResults() const {
  if (cancelled_) {
    return net::AddressList();
  }

  DCHECK(internal_request_);
  return internal_request_->GetAddressResults();
}

net::HostResolverEndpointResults ResolveHostRequest::GetAlternativeEndpoints()
    const {
  if (cancelled_) {
    return {};
  }

  DCHECK(internal_request_);
  auto endpoints = internal_request_->GetEndpointResults();

  // `endpoints` contains both alternative endpoints (from HTTPS/SVCB) and
  // authority endpoints (from A/AAAA directly). The authority endpoints are
  // redundant with `AddressList`, so return only the alternative endpoints.
  //
  // TODO(crbug.com/40203587): This is the opposite of the design taken
  // everywhere else in the DNS logic, where we aimed to migrate `AddressList`
  // to `HostResolverEndpointResult`.
  net::HostResolverEndpointResults alternative_endpoints;
  std::ranges::copy_if(
      endpoints, std::back_inserter(alternative_endpoints),
      [](const auto& endpoint) { return endpoint.metadata.IsAlternative(); });
  return alternative_endpoints;
}

void ResolveHostRequest::SignalNonAddressResults() {
  if (cancelled_) {
    return;
  }
  DCHECK(internal_request_);

  if (!internal_request_->GetTextResults().empty()) {
    response_client_->OnTextResults(
        base::ToVector(internal_request_->GetTextResults()));
  }

  if (!internal_request_->GetHostnameResults().empty()) {
    response_client_->OnHostnameResults(
        base::ToVector(internal_request_->GetHostnameResults()));
  }
}

}  // namespace network
