// Copyright 2014 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 "components/domain_reliability/monitor.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "base/message_loop/message_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/task_runner.h"
#include "base/threading/thread_checker.h"
#include "base/time/time.h"
#include "components/domain_reliability/baked_in_configs.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_getter.h"

namespace domain_reliability {

DomainReliabilityMonitor::DomainReliabilityMonitor(
    const std::string& upload_reporter_string)
    : time_(new ActualTime()),
      upload_reporter_string_(upload_reporter_string),
      scheduler_params_(
          DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()),
      dispatcher_(time_.get()),
      was_cleared_(false),
      cleared_mode_(MAX_CLEAR_MODE),
      weak_factory_(this) {}

DomainReliabilityMonitor::DomainReliabilityMonitor(
    const std::string& upload_reporter_string,
    scoped_ptr<MockableTime> time)
    : time_(time.Pass()),
      upload_reporter_string_(upload_reporter_string),
      scheduler_params_(
          DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()),
      dispatcher_(time_.get()),
      was_cleared_(false),
      cleared_mode_(MAX_CLEAR_MODE),
      weak_factory_(this) {}

DomainReliabilityMonitor::~DomainReliabilityMonitor() {
  ClearContexts();
}

void DomainReliabilityMonitor::Init(
    net::URLRequestContext* url_request_context,
    const scoped_refptr<base::SingleThreadTaskRunner>& task_runner) {
  DCHECK(!thread_checker_);

  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter =
      new net::TrivialURLRequestContextGetter(url_request_context,
                                              task_runner);
  Init(url_request_context_getter);
}

void DomainReliabilityMonitor::Init(
    scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
  DCHECK(!thread_checker_);

  DCHECK(url_request_context_getter->GetNetworkTaskRunner()->
         RunsTasksOnCurrentThread());

  uploader_ = DomainReliabilityUploader::Create(url_request_context_getter);
  thread_checker_.reset(new base::ThreadChecker());
}

void DomainReliabilityMonitor::AddBakedInConfigs() {
  DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread());
  base::Time now = base::Time::Now();
  for (size_t i = 0; kBakedInJsonConfigs[i]; ++i) {
    std::string json(kBakedInJsonConfigs[i]);
    scoped_ptr<const DomainReliabilityConfig> config =
        DomainReliabilityConfig::FromJSON(json);
    if (config && config->IsExpired(now)) {
      LOG(WARNING) << "Baked-in Domain Reliability config for "
                   << config->domain << " is expired.";
      continue;
    }
    AddContext(config.Pass());
  }
}

void DomainReliabilityMonitor::OnBeforeRedirect(net::URLRequest* request) {
  DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread());
  // Record the redirect itself in addition to the final request.
  OnRequestLegComplete(RequestInfo(*request));
}

void DomainReliabilityMonitor::OnCompleted(net::URLRequest* request,
                                           bool started) {
  DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread());
  if (!started)
    return;
  RequestInfo request_info(*request);
  if (request_info.AccessedNetwork()) {
    OnRequestLegComplete(request_info);
    // A request was just using the network, so now is a good time to run any
    // pending and eligible uploads.
    dispatcher_.RunEligibleTasks();
  }
}

void DomainReliabilityMonitor::ClearBrowsingData(
   DomainReliabilityClearMode mode) {
  DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread());

  was_cleared_ = true;
  cleared_mode_ = mode;

  switch (mode) {
    case CLEAR_BEACONS: {
      ContextMap::const_iterator it;
      for (it = contexts_.begin(); it != contexts_.end(); ++it)
        it->second->ClearBeacons();
      break;
    };
    case CLEAR_CONTEXTS:
      ClearContexts();
      break;
    case MAX_CLEAR_MODE:
      NOTREACHED();
  }
}

DomainReliabilityContext* DomainReliabilityMonitor::AddContextForTesting(
    scoped_ptr<const DomainReliabilityConfig> config) {
  DCHECK(thread_checker_ && thread_checker_->CalledOnValidThread());
  return AddContext(config.Pass());
}

DomainReliabilityMonitor::RequestInfo::RequestInfo() {}

DomainReliabilityMonitor::RequestInfo::RequestInfo(
    const net::URLRequest& request)
    : url(request.url()),
      status(request.status()),
      response_info(request.response_info()),
      load_flags(request.load_flags()),
      is_upload(DomainReliabilityUploader::URLRequestIsUpload(request)) {
  request.GetLoadTimingInfo(&load_timing_info);
}

DomainReliabilityMonitor::RequestInfo::~RequestInfo() {}

bool DomainReliabilityMonitor::RequestInfo::AccessedNetwork() const {
  return status.status() != net::URLRequestStatus::CANCELED &&
     response_info.network_accessed;
}

DomainReliabilityContext* DomainReliabilityMonitor::AddContext(
    scoped_ptr<const DomainReliabilityConfig> config) {
  DCHECK(config);
  DCHECK(config->IsValid());

  // Grab a copy of the domain before transferring ownership of |config|.
  std::string domain = config->domain;

  DomainReliabilityContext* context =
      new DomainReliabilityContext(time_.get(),
                                   scheduler_params_,
                                   upload_reporter_string_,
                                   &dispatcher_,
                                   uploader_.get(),
                                   config.Pass());

  std::pair<ContextMap::iterator, bool> map_it =
      contexts_.insert(make_pair(domain, context));
  // Make sure the domain wasn't already in the map.
  DCHECK(map_it.second);

  return map_it.first->second;
}

void DomainReliabilityMonitor::ClearContexts() {
  STLDeleteContainerPairSecondPointers(
      contexts_.begin(), contexts_.end());
  contexts_.clear();
}

void DomainReliabilityMonitor::OnRequestLegComplete(
    const RequestInfo& request) {
  int response_code;
  if (request.response_info.headers)
    response_code = request.response_info.headers->response_code();
  else
    response_code = -1;
  ContextMap::iterator context_it;
  std::string beacon_status;

  int error_code = net::OK;
  if (request.status.status() == net::URLRequestStatus::FAILED)
    error_code = request.status.error();

  // Ignore requests where:
  // 1. There is no context for the request host.
  // 2. The request did not access the network.
  // 3. The request is not supposed to send cookies (to avoid associating the
  //    request with any potentially unique data in the config).
  // 4. The request was itself a Domain Reliability upload (to avoid loops).
  // 5. There is no defined beacon status for the error or HTTP response code
  //    (to avoid leaking network-local errors).
  if ((context_it = contexts_.find(request.url.host())) == contexts_.end() ||
      !request.AccessedNetwork() ||
      (request.load_flags & net::LOAD_DO_NOT_SEND_COOKIES) ||
      request.is_upload ||
      !GetDomainReliabilityBeaconStatus(
          error_code, response_code, &beacon_status)) {
    return;
  }

  DomainReliabilityBeacon beacon;
  beacon.status = beacon_status;
  beacon.chrome_error = error_code;
  if (!request.response_info.was_fetched_via_proxy)
    beacon.server_ip = request.response_info.socket_address.host();
  else
    beacon.server_ip.clear();
  beacon.http_response_code = response_code;
  beacon.start_time = request.load_timing_info.request_start;
  beacon.elapsed = time_->NowTicks() - beacon.start_time;
  context_it->second->OnBeacon(request.url, beacon);
}

base::WeakPtr<DomainReliabilityMonitor>
DomainReliabilityMonitor::MakeWeakPtr() {
  return weak_factory_.GetWeakPtr();
}

}  // namespace domain_reliability
