// Copyright 2018 The Chromium OS 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 "shill/http_request.h"

#include <curl/curl.h>
#include <string>
#include <utility>

#include <base/bind.h>
#include <base/strings/string_number_conversions.h>
#include <base/time/time.h>
#include <brillo/http/http_utils.h>

#include "shill/connection.h"
#include "shill/dns_client.h"
#include "shill/error.h"
#include "shill/event_dispatcher.h"
#include "shill/http_url.h"
#include "shill/logging.h"
#include "shill/net/ip_address.h"
#include "shill/net/sockets.h"

using base::Bind;
using base::Callback;
using base::StringToInt;
using std::string;

namespace {

// The curl error domain for http requests
const char kCurlEasyError[] = "curl_easy_error";

}  // namespace

namespace shill {

namespace Logging {
static auto kModuleLogScope = ScopeLogger::kHTTP;
static string ObjectID(Connection* c) { return c->interface_name(); }
}

const int HttpRequest::kRequestTimeoutSeconds = 10;

HttpRequest::HttpRequest(ConnectionRefPtr connection,
                         EventDispatcher* dispatcher,
                         bool allow_non_google_https)
    : connection_(connection),
      weak_ptr_factory_(this),
      dns_client_callback_(
          Bind(&HttpRequest::GetDNSResult, weak_ptr_factory_.GetWeakPtr())),
      success_callback_(
          Bind(&HttpRequest::SuccessCallback, weak_ptr_factory_.GetWeakPtr())),
      error_callback_(
          Bind(&HttpRequest::ErrorCallback, weak_ptr_factory_.GetWeakPtr())),
      dns_client_(new DnsClient(connection->IsIPv6() ? IPAddress::kFamilyIPv6
                                                     : IPAddress::kFamilyIPv4,
                                connection->interface_name(),
                                connection->dns_servers(),
                                DnsClient::kDnsTimeoutMilliseconds,
                                dispatcher,
                                dns_client_callback_)),
      transport_(brillo::http::Transport::CreateDefault()),
      request_id_(-1),
      server_port_(-1),
      is_running_(false) {
  if (allow_non_google_https) {
    transport_->UseCustomCertificate(
      brillo::http::Transport::Certificate::kNss);
  }
}

HttpRequest::~HttpRequest() {
  Stop();
}

HttpRequest::Result HttpRequest::Start(
    const string& url_string,
    const Callback<void(std::shared_ptr<brillo::http::Response>)>&
        request_success_callback,
    const Callback<void(Result)>& request_error_callback) {
  SLOG(connection_.get(), 3) << "In " << __func__;

  DCHECK(!is_running_);

  HttpUrl url;
  if (!url.ParseFromString(url_string)) {
    LOG(ERROR) << "Failed to parse URL string: " << url_string;
    return kResultInvalidInput;
  }
  url_string_ = url_string;
  is_running_ = true;
  server_hostname_ = url.host();
  server_port_ = url.port();
  server_path_ = url.path();
  connection_->RequestRouting();
  transport_->SetDefaultTimeout(
      base::TimeDelta::FromSeconds(kRequestTimeoutSeconds));

  IPAddress addr(IPAddress::kFamilyIPv4);
  if (connection_->IsIPv6()) {
    addr.set_family(IPAddress::kFamilyIPv6);
  }

  request_success_callback_ = request_success_callback;
  request_error_callback_ = request_error_callback;

  if (addr.SetAddressFromString(server_hostname_)) {
    StartRequest();
  } else {
    SLOG(connection_.get(), 3) << "Looking up host: " << server_hostname_;
    Error error;
    if (!dns_client_->Start(server_hostname_, &error)) {
      LOG(ERROR) << "Failed to start DNS client: " << error.message();
      Stop();
      return kResultDNSFailure;
    }
  }

  return kResultInProgress;
}

void HttpRequest::StartRequest() {
  request_id_ = brillo::http::Get(url_string_, {}, transport_,
                                  success_callback_, error_callback_);
}

void HttpRequest::SuccessCallback(
    brillo::http::RequestID request_id,
    std::unique_ptr<brillo::http::Response> response) {
  if (request_id != request_id_) {
    LOG(ERROR) << "Expected request ID " << request_id_ << " but got "
               << request_id;
    SendStatus(kResultUnknown);
    return;
  }

  Callback<void(std::shared_ptr<brillo::http::Response>)>
      request_success_callback = request_success_callback_;
  Stop();

  if (!request_success_callback.is_null()) {
    request_success_callback.Run(std::move(response));
  }
}

void HttpRequest::ErrorCallback(brillo::http::RequestID request_id,
                                const brillo::Error* error) {
  int error_code;
  if (error->GetDomain() != kCurlEasyError) {
    LOG(ERROR) << "Expected error domain " << kCurlEasyError << " but got "
               << error->GetDomain();
    SendStatus(kResultUnknown);
    return;
  }
  if (request_id != request_id_) {
    LOG(ERROR) << "Expected request ID " << request_id_ << " but got "
               << request_id;
    SendStatus(kResultUnknown);
    return;
  }
  if (!StringToInt(error->GetCode(), &error_code)) {
    LOG(ERROR) << "Unable to convert error code " << error->GetCode()
               << " to Int";
    SendStatus(kResultUnknown);
    return;
  }

  // TODO(matthewmwang): This breaks abstraction. Modify brillo::http::Transport
  // to provide an implementation agnostic error code.
  switch (error_code) {
    case CURLE_COULDNT_CONNECT:
      SendStatus(kResultConnectionFailure);
      break;
    case CURLE_WRITE_ERROR:
    case CURLE_READ_ERROR:
      SendStatus(kResultHTTPFailure);
      break;
    case CURLE_OPERATION_TIMEDOUT:
      SendStatus(kResultHTTPTimeout);
      break;
    default:
      SendStatus(kResultUnknown);
  }
}

void HttpRequest::Stop() {
  SLOG(connection_.get(), 3) << "In " << __func__ << "; running is "
                             << is_running_;

  if (!is_running_) {
    return;
  }

  // Clear IO handlers first so that closing the socket doesn't cause
  // events to fire.
  connection_->ReleaseRouting();
  dns_client_->Stop();
  is_running_ = false;
  request_id_ = -1;
  server_hostname_.clear();
  server_path_.clear();
  server_port_ = -1;
  request_error_callback_.Reset();
  request_success_callback_.Reset();
}

// DnsClient callback that fires when the DNS request completes.
void HttpRequest::GetDNSResult(const Error& error, const IPAddress& address) {
  SLOG(connection_.get(), 3) << "In " << __func__;
  if (!error.IsSuccess()) {
    LOG(ERROR) << "Could not resolve hostname "
               << server_hostname_
               << ": "
               << error.message();
    if (error.message() == DnsClient::kErrorTimedOut) {
      SendStatus(kResultDNSTimeout);
    } else {
      SendStatus(kResultDNSFailure);
    }
    return;
  }

  string addr_string;
  if (!address.IntoString(&addr_string)) {
    SendStatus(kResultDNSFailure);
    return;
  }

  // Add the host/port to IP mapping to the DNS cache to force curl to resolve
  // the URL to the given IP. Otherwise, will do its own DNS resolution and not
  // use the IP we provide to it.
  transport_->ResolveHostToIp(server_hostname_, server_port_, addr_string);
  StartRequest();
}

void HttpRequest::SendStatus(Result result) {
  // Save copies on the stack, since Stop() will remove them.
  Callback<void(Result)> request_error_callback = request_error_callback_;
  Stop();

  // Call the callback last, since it may delete us and |this| may no longer
  // be valid.
  if (!request_error_callback.is_null()) {
    request_error_callback.Run(result);
  }
}

}  // namespace shill
