// Copyright (c) 2012 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 "chrome/service/cloud_print/cloud_print_url_fetcher.h"

#include <stddef.h>

#include "base/metrics/histogram.h"
#include "base/strings/stringprintf.h"
#include "base/values.h"
#include "chrome/common/cloud_print/cloud_print_constants.h"
#include "chrome/common/cloud_print/cloud_print_helpers.h"
#include "chrome/service/cloud_print/cloud_print_service_helpers.h"
#include "chrome/service/cloud_print/cloud_print_token_store.h"
#include "chrome/service/net/service_url_request_context_getter.h"
#include "chrome/service/service_process.h"
#include "net/base/load_flags.h"
#include "net/http/http_status_code.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_status.h"
#include "url/gurl.h"

namespace cloud_print {

namespace {

void ReportRequestTime(CloudPrintURLFetcher::RequestType type,
                       base::TimeDelta time) {
  if (type == CloudPrintURLFetcher::REQUEST_REGISTER) {
    UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.Register", time);
  } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) {
    UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.UpdatePrinter", time);
  } else if (type == CloudPrintURLFetcher::REQUEST_DATA) {
    UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.DownloadData", time);
  } else {
    UMA_HISTOGRAM_TIMES("CloudPrint.UrlFetcherRequestTime.Other", time);
  }
}

void ReportRetriesCount(CloudPrintURLFetcher::RequestType type,
                        int retries) {
  if (type == CloudPrintURLFetcher::REQUEST_REGISTER) {
    UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.Register", retries);
  } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) {
    UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.UpdatePrinter",
                             retries);
  } else if (type == CloudPrintURLFetcher::REQUEST_DATA) {
    UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.DownloadData",
                             retries);
  } else {
    UMA_HISTOGRAM_COUNTS_100("CloudPrint.UrlFetcherRetries.Other", retries);
  }
}

void ReportDownloadSize(CloudPrintURLFetcher::RequestType type, size_t size) {
  if (type == CloudPrintURLFetcher::REQUEST_REGISTER) {
    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.Register", size);
  } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) {
    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.UpdatePrinter",
                            size);
  } else if (type == CloudPrintURLFetcher::REQUEST_DATA) {
    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.DownloadData",
                            size);
  } else {
    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherDownloadSize.Other", size);
  }
}

void ReportUploadSize(CloudPrintURLFetcher::RequestType type, size_t size) {
  if (type == CloudPrintURLFetcher::REQUEST_REGISTER) {
    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.Register", size);
  } else if (type == CloudPrintURLFetcher::REQUEST_UPDATE_PRINTER) {
    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.UpdatePrinter",
                            size);
  } else if (type == CloudPrintURLFetcher::REQUEST_DATA) {
    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.DownloadData",
                            size);
  } else {
    UMA_HISTOGRAM_MEMORY_KB("CloudPrint.UrlFetcherUploadSize.Other", size);
  }
}

CloudPrintURLFetcherFactory* g_factory = NULL;

}  // namespace

// virtual
CloudPrintURLFetcherFactory::~CloudPrintURLFetcherFactory() {}

// static
CloudPrintURLFetcher* CloudPrintURLFetcher::Create() {
  CloudPrintURLFetcherFactory* factory = CloudPrintURLFetcher::factory();
  return factory ? factory->CreateCloudPrintURLFetcher() :
      new CloudPrintURLFetcher;
}

// static
CloudPrintURLFetcherFactory* CloudPrintURLFetcher::factory() {
  return g_factory;
}

// static
void CloudPrintURLFetcher::set_factory(CloudPrintURLFetcherFactory* factory) {
  g_factory = factory;
}

CloudPrintURLFetcher::ResponseAction
CloudPrintURLFetcher::Delegate::HandleRawResponse(
    const net::URLFetcher* source,
    const GURL& url,
    const net::URLRequestStatus& status,
    int response_code,
    const net::ResponseCookies& cookies,
    const std::string& data) {
  return CONTINUE_PROCESSING;
}

CloudPrintURLFetcher::ResponseAction
CloudPrintURLFetcher::Delegate::HandleRawData(
    const net::URLFetcher* source,
    const GURL& url,
    const std::string& data) {
  return CONTINUE_PROCESSING;
}

CloudPrintURLFetcher::ResponseAction
CloudPrintURLFetcher::Delegate::HandleJSONData(
    const net::URLFetcher* source,
    const GURL& url,
    base::DictionaryValue* json_data,
    bool succeeded) {
  return CONTINUE_PROCESSING;
}

CloudPrintURLFetcher::CloudPrintURLFetcher()
    : delegate_(NULL),
      num_retries_(0),
      type_(REQUEST_MAX) {
}

bool CloudPrintURLFetcher::IsSameRequest(const net::URLFetcher* source) {
  return (request_.get() == source);
}

void CloudPrintURLFetcher::StartGetRequest(
    RequestType type,
    const GURL& url,
    Delegate* delegate,
    int max_retries,
    const std::string& additional_headers) {
  StartRequestHelper(type, url, net::URLFetcher::GET, delegate, max_retries,
                     std::string(), std::string(), additional_headers);
}

void CloudPrintURLFetcher::StartPostRequest(
    RequestType type,
    const GURL& url,
    Delegate* delegate,
    int max_retries,
    const std::string& post_data_mime_type,
    const std::string& post_data,
    const std::string& additional_headers) {
  StartRequestHelper(type, url, net::URLFetcher::POST, delegate, max_retries,
                     post_data_mime_type, post_data, additional_headers);
}

void CloudPrintURLFetcher::OnURLFetchComplete(
    const net::URLFetcher* source) {
  VLOG(1) << "CP_PROXY: OnURLFetchComplete, url: " << source->GetURL()
          << ", response code: " << source->GetResponseCode();
  // Make sure we stay alive through the body of this function.
  scoped_refptr<CloudPrintURLFetcher> keep_alive(this);
  std::string data;
  source->GetResponseAsString(&data);
  ReportRequestTime(type_, base::Time::Now() - start_time_);
  ReportDownloadSize(type_, data.size());
  ResponseAction action = delegate_->HandleRawResponse(
      source,
      source->GetURL(),
      source->GetStatus(),
      source->GetResponseCode(),
      source->GetCookies(),
      data);

  // If we get auth error, notify delegate and check if it wants to proceed.
  if (action == CONTINUE_PROCESSING &&
      source->GetResponseCode() == net::HTTP_FORBIDDEN) {
    action = delegate_->OnRequestAuthError();
  }

  if (action == CONTINUE_PROCESSING) {
    // We need to retry on all network errors.
    if (!source->GetStatus().is_success() || (source->GetResponseCode() != 200))
      action = RETRY_REQUEST;
    else
      action = delegate_->HandleRawData(source, source->GetURL(), data);

    if (action == CONTINUE_PROCESSING) {
      // If the delegate is not interested in handling the raw response data,
      // we assume that a JSON response is expected. If we do not get a JSON
      // response, we will retry (to handle the case where we got redirected
      // to a non-cloudprint-server URL eg. for authentication).
      bool succeeded = false;
      scoped_ptr<base::DictionaryValue> response_dict =
          ParseResponseJSON(data, &succeeded);

      if (response_dict) {
        action = delegate_->HandleJSONData(source,
                                           source->GetURL(),
                                           response_dict.get(),
                                           succeeded);
      } else {
        action = RETRY_REQUEST;
      }
    }
  }
  // Retry the request if needed.
  if (action == RETRY_REQUEST) {
    // Explicitly call ReceivedContentWasMalformed() to ensure the current
    // request gets counted as a failure for calculation of the back-off
    // period.  If it was already a failure by status code, this call will
    // be ignored.
    request_->ReceivedContentWasMalformed();

    // If we receive error code from the server "Media Type Not Supported",
    // there is no reason to retry, request will never succeed.
    // In that case we should call OnRequestGiveUp() right away.
    if (source->GetResponseCode() == net::HTTP_UNSUPPORTED_MEDIA_TYPE)
      num_retries_ = source->GetMaxRetriesOn5xx();

    ++num_retries_;
    if ((-1 != source->GetMaxRetriesOn5xx()) &&
        (num_retries_ > source->GetMaxRetriesOn5xx())) {
      // Retry limit reached. Give up.
      delegate_->OnRequestGiveUp();
      action = STOP_PROCESSING;
    } else {
      // Either no retry limit specified or retry limit has not yet been
      // reached. Try again. Set up the request headers again because the token
      // may have changed.
      SetupRequestHeaders();
      request_->SetRequestContext(GetRequestContextGetter());
      start_time_ = base::Time::Now();
      request_->Start();
    }
  }
  if (action != RETRY_REQUEST) {
    ReportRetriesCount(type_, num_retries_);
  }
}

void CloudPrintURLFetcher::StartRequestHelper(
    RequestType type,
    const GURL& url,
    net::URLFetcher::RequestType request_type,
    Delegate* delegate,
    int max_retries,
    const std::string& post_data_mime_type,
    const std::string& post_data,
    const std::string& additional_headers) {
  DCHECK(delegate);
  type_ = type;
  UMA_HISTOGRAM_ENUMERATION("CloudPrint.UrlFetcherRequestType", type,
                            REQUEST_MAX);
  // Persist the additional headers in case we need to retry the request.
  additional_headers_ = additional_headers;
  request_ = net::URLFetcher::Create(0, url, request_type, this);
  request_->SetRequestContext(GetRequestContextGetter());
  // Since we implement our own retry logic, disable the retry in URLFetcher.
  request_->SetAutomaticallyRetryOn5xx(false);
  request_->SetMaxRetriesOn5xx(max_retries);
  delegate_ = delegate;
  SetupRequestHeaders();
  request_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
                         net::LOAD_DO_NOT_SAVE_COOKIES);
  if (request_type == net::URLFetcher::POST) {
    request_->SetUploadData(post_data_mime_type, post_data);
    ReportUploadSize(type_, post_data.size());
  }
  start_time_ = base::Time::Now();
  request_->Start();
}

void CloudPrintURLFetcher::SetupRequestHeaders() {
  std::string headers = delegate_->GetAuthHeader();
  if (!headers.empty())
    headers += "\r\n";
  headers += kChromeCloudPrintProxyHeader;
  if (!additional_headers_.empty()) {
    headers += "\r\n";
    headers += additional_headers_;
  }
  request_->SetExtraRequestHeaders(headers);
}

CloudPrintURLFetcher::~CloudPrintURLFetcher() {}

net::URLRequestContextGetter* CloudPrintURLFetcher::GetRequestContextGetter() {
  ServiceURLRequestContextGetter* getter =
      g_service_process->GetServiceURLRequestContextGetter();
  // Now set up the user agent for cloudprint.
  std::string user_agent = getter->user_agent();
  base::StringAppendF(&user_agent, " %s", kCloudPrintUserAgent);
  getter->set_user_agent(user_agent);
  return getter;
}

}  // namespace cloud_print
