// 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 "net/url_request/url_fetcher_impl.h"

#include <utility>

#include "base/bind.h"
#include "base/sequenced_task_runner.h"
#include "net/base/upload_data_stream.h"
#include "net/url_request/url_fetcher_core.h"
#include "net/url_request/url_fetcher_factory.h"
#include "net/url_request/url_fetcher_response_writer.h"

namespace net {

static URLFetcherFactory* g_factory = NULL;

URLFetcherImpl::URLFetcherImpl(
    const GURL& url,
    RequestType request_type,
    URLFetcherDelegate* d,
    net::NetworkTrafficAnnotationTag traffic_annotation)
    : core_(
          new URLFetcherCore(this, url, request_type, d, traffic_annotation)) {}

URLFetcherImpl::~URLFetcherImpl() {
  core_->Stop();
}

void URLFetcherImpl::SetUploadData(const std::string& upload_content_type,
                                   const std::string& upload_content) {
  core_->SetUploadData(upload_content_type, upload_content);
}

void URLFetcherImpl::SetUploadFilePath(
    const std::string& upload_content_type,
    const base::FilePath& file_path,
    uint64_t range_offset,
    uint64_t range_length,
    scoped_refptr<base::TaskRunner> file_task_runner) {
  core_->SetUploadFilePath(upload_content_type,
                           file_path,
                           range_offset,
                           range_length,
                           file_task_runner);
}

void URLFetcherImpl::SetUploadStreamFactory(
    const std::string& upload_content_type,
    const CreateUploadStreamCallback& callback) {
  core_->SetUploadStreamFactory(upload_content_type, callback);
}

void URLFetcherImpl::SetChunkedUpload(const std::string& content_type) {
  core_->SetChunkedUpload(content_type);
}

void URLFetcherImpl::AppendChunkToUpload(const std::string& data,
                                         bool is_last_chunk) {
  DCHECK(data.length());
  core_->AppendChunkToUpload(data, is_last_chunk);
}

void URLFetcherImpl::SetReferrer(const std::string& referrer) {
  core_->SetReferrer(referrer);
}

void URLFetcherImpl::SetReferrerPolicy(
    URLRequest::ReferrerPolicy referrer_policy) {
  core_->SetReferrerPolicy(referrer_policy);
}

void URLFetcherImpl::SetLoadFlags(int load_flags) {
  core_->SetLoadFlags(load_flags);
}

void URLFetcherImpl::SetAllowCredentials(bool allow_credentials) {
  core_->SetAllowCredentials(allow_credentials);
}

int URLFetcherImpl::GetLoadFlags() const {
  return core_->GetLoadFlags();
}

void URLFetcherImpl::SetExtraRequestHeaders(
    const std::string& extra_request_headers) {
  core_->SetExtraRequestHeaders(extra_request_headers);
}

void URLFetcherImpl::AddExtraRequestHeader(const std::string& header_line) {
  core_->AddExtraRequestHeader(header_line);
}

void URLFetcherImpl::SetRequestContext(
    URLRequestContextGetter* request_context_getter) {
  core_->SetRequestContext(request_context_getter);
}

void URLFetcherImpl::SetInitiator(
    const base::Optional<url::Origin>& initiator) {
  core_->SetInitiator(initiator);
}

void URLFetcherImpl::SetURLRequestUserData(
    const void* key,
    const CreateDataCallback& create_data_callback) {
  core_->SetURLRequestUserData(key, create_data_callback);
}

void URLFetcherImpl::SetStopOnRedirect(bool stop_on_redirect) {
  core_->SetStopOnRedirect(stop_on_redirect);
}

void URLFetcherImpl::SetAutomaticallyRetryOn5xx(bool retry) {
  core_->SetAutomaticallyRetryOn5xx(retry);
}

void URLFetcherImpl::SetMaxRetriesOn5xx(int max_retries) {
  core_->SetMaxRetriesOn5xx(max_retries);
}

int URLFetcherImpl::GetMaxRetriesOn5xx() const {
  return core_->GetMaxRetriesOn5xx();
}


base::TimeDelta URLFetcherImpl::GetBackoffDelay() const {
  return core_->GetBackoffDelay();
}

void URLFetcherImpl::SetAutomaticallyRetryOnNetworkChanges(int max_retries) {
  core_->SetAutomaticallyRetryOnNetworkChanges(max_retries);
}

void URLFetcherImpl::SaveResponseToFileAtPath(
    const base::FilePath& file_path,
    scoped_refptr<base::SequencedTaskRunner> file_task_runner) {
  core_->SaveResponseToFileAtPath(file_path, file_task_runner);
}

void URLFetcherImpl::SaveResponseToTemporaryFile(
    scoped_refptr<base::SequencedTaskRunner> file_task_runner) {
  core_->SaveResponseToTemporaryFile(file_task_runner);
}

void URLFetcherImpl::SaveResponseWithWriter(
    std::unique_ptr<URLFetcherResponseWriter> response_writer) {
  core_->SaveResponseWithWriter(std::move(response_writer));
}

HttpResponseHeaders* URLFetcherImpl::GetResponseHeaders() const {
  return core_->GetResponseHeaders();
}

HostPortPair URLFetcherImpl::GetSocketAddress() const {
  return core_->GetSocketAddress();
}

const ProxyServer& URLFetcherImpl::ProxyServerUsed() const {
  return core_->ProxyServerUsed();
}

bool URLFetcherImpl::WasFetchedViaProxy() const {
  return core_->WasFetchedViaProxy();
}

bool URLFetcherImpl::WasCached() const {
  return core_->WasCached();
}

int64_t URLFetcherImpl::GetReceivedResponseContentLength() const {
  return core_->GetReceivedResponseContentLength();
}

int64_t URLFetcherImpl::GetTotalReceivedBytes() const {
  return core_->GetTotalReceivedBytes();
}

void URLFetcherImpl::Start() {
  core_->Start();
}

const GURL& URLFetcherImpl::GetOriginalURL() const {
  return core_->GetOriginalURL();
}

const GURL& URLFetcherImpl::GetURL() const {
  return core_->GetURL();
}

const URLRequestStatus& URLFetcherImpl::GetStatus() const {
  return core_->GetStatus();
}

int URLFetcherImpl::GetResponseCode() const {
  return core_->GetResponseCode();
}

void URLFetcherImpl::ReceivedContentWasMalformed() {
  core_->ReceivedContentWasMalformed();
}

bool URLFetcherImpl::GetResponseAsString(
    std::string* out_response_string) const {
  return core_->GetResponseAsString(out_response_string);
}

bool URLFetcherImpl::GetResponseAsFilePath(
    bool take_ownership,
    base::FilePath* out_response_path) const {
  return core_->GetResponseAsFilePath(take_ownership, out_response_path);
}

// static
void URLFetcherImpl::CancelAll() {
  URLFetcherCore::CancelAll();
}

// static
void URLFetcherImpl::SetIgnoreCertificateRequests(bool ignored) {
  URLFetcherCore::SetIgnoreCertificateRequests(ignored);
}

// static
int URLFetcherImpl::GetNumFetcherCores() {
  return URLFetcherCore::GetNumFetcherCores();
}

URLFetcherDelegate* URLFetcherImpl::delegate() const {
  return core_->delegate();
}

// static
URLFetcherFactory* URLFetcherImpl::factory() {
  return g_factory;
}

// static
void URLFetcherImpl::set_factory(URLFetcherFactory* factory) {
  g_factory = factory;
}

}  // namespace net
