// 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);
}

#if defined(STARBOARD)
void URLFetcherImpl::SaveResponseToLargeString() {
  core_->SaveResponseToLargeString();
}
#endif

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

#if defined(STARBOARD)
URLFetcherResponseWriter* URLFetcherImpl::GetResponseWriter() const {
  return core_->GetResponseWriter();
}
#endif

const HttpRequestHeaders& URLFetcherImpl::GetRequestHeaders() const {
  return core_->GetRequestHeaders();
}

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);
}

#if defined(STARBOARD)
bool URLFetcherImpl::GetResponseAsLargeString(
    std::string* out_response_string) const {
  return core_->GetResponseAsLargeString(out_response_string);
}
#endif

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
