// 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/test_url_fetcher_factory.h"

#include <string>

#include "base/bind.h"
#include "base/compiler_specific.h"
#include "base/file_util.h"
#include "base/memory/weak_ptr.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread_restrictions.h"
#include "net/base/host_port_pair.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/http/http_response_headers.h"
#include "net/url_request/url_fetcher_delegate.h"
#include "net/url_request/url_fetcher_impl.h"
#include "net/url_request/url_fetcher_response_writer.h"
#include "net/url_request/url_request_status.h"

namespace net {

ScopedURLFetcherFactory::ScopedURLFetcherFactory(
    URLFetcherFactory* factory) {
  DCHECK(!URLFetcherImpl::factory());
  URLFetcherImpl::set_factory(factory);
}

ScopedURLFetcherFactory::~ScopedURLFetcherFactory() {
  DCHECK(URLFetcherImpl::factory());
  URLFetcherImpl::set_factory(NULL);
}

TestURLFetcher::TestURLFetcher(int id,
                               const GURL& url,
                               URLFetcherDelegate* d)
    : owner_(NULL),
      id_(id),
      original_url_(url),
      delegate_(d),
      delegate_for_tests_(NULL),
      did_receive_last_chunk_(false),
      fake_load_flags_(0),
      fake_response_code_(-1),
      fake_response_destination_(STRING),
      fake_was_fetched_via_proxy_(false),
      fake_max_retries_(0) {
}

TestURLFetcher::~TestURLFetcher() {
  if (delegate_for_tests_)
    delegate_for_tests_->OnRequestEnd(id_);
  if (owner_)
    owner_->RemoveFetcherFromMap(id_);
}

void TestURLFetcher::SetUploadData(const std::string& upload_content_type,
                                   const std::string& upload_content) {
  upload_data_ = upload_content;
}

void TestURLFetcher::SetUploadFilePath(
    const std::string& upload_content_type,
    const base::FilePath& file_path,
    uint64 range_offset,
    uint64 range_length,
    scoped_refptr<base::TaskRunner> file_task_runner) {
  upload_file_path_ = file_path;
}

void TestURLFetcher::SetChunkedUpload(const std::string& upload_content_type) {
}

void TestURLFetcher::AppendChunkToUpload(const std::string& data,
                                         bool is_last_chunk) {
  DCHECK(!did_receive_last_chunk_);
  did_receive_last_chunk_ = is_last_chunk;
  chunks_.push_back(data);
  if (delegate_for_tests_)
    delegate_for_tests_->OnChunkUpload(id_);
}

void TestURLFetcher::SetLoadFlags(int load_flags) {
  fake_load_flags_= load_flags;
}

int TestURLFetcher::GetLoadFlags() const {
  return fake_load_flags_;
}

void TestURLFetcher::SetReferrer(const std::string& referrer) {
}

void TestURLFetcher::SetReferrerPolicy(
    URLRequest::ReferrerPolicy referrer_policy) {
}

void TestURLFetcher::SetExtraRequestHeaders(
    const std::string& extra_request_headers) {
  fake_extra_request_headers_.Clear();
  fake_extra_request_headers_.AddHeadersFromString(extra_request_headers);
}

void TestURLFetcher::AddExtraRequestHeader(const std::string& header_line) {
  fake_extra_request_headers_.AddHeaderFromString(header_line);
}

void TestURLFetcher::SetRequestContext(
    URLRequestContextGetter* request_context_getter) {
}

void TestURLFetcher::SetFirstPartyForCookies(
    const GURL& first_party_for_cookies) {
}

void TestURLFetcher::SetURLRequestUserData(
    const void* key,
    const CreateDataCallback& create_data_callback) {
}

void TestURLFetcher::SetStopOnRedirect(bool stop_on_redirect) {
}

void TestURLFetcher::SetAutomaticallyRetryOn5xx(bool retry) {
}

void TestURLFetcher::SetMaxRetriesOn5xx(int max_retries) {
  fake_max_retries_ = max_retries;
}

int TestURLFetcher::GetMaxRetriesOn5xx() const {
  return fake_max_retries_;
}

base::TimeDelta TestURLFetcher::GetBackoffDelay() const {
  return fake_backoff_delay_;
}

void TestURLFetcher::SetAutomaticallyRetryOnNetworkChanges(int max_retries) {
}

void TestURLFetcher::SaveResponseToFileAtPath(
    const base::FilePath& file_path,
    scoped_refptr<base::SequencedTaskRunner> file_task_runner) {
  SetResponseFilePath(file_path);
  // Asynchronous IO is not supported, so file_task_runner is ignored.
  base::ThreadRestrictions::ScopedAllowIO allow_io;
  const size_t written_bytes = base::WriteFile(
      file_path, fake_response_string_.c_str(), fake_response_string_.size());
  DCHECK_EQ(written_bytes, fake_response_string_.size());
}

void TestURLFetcher::SaveResponseToTemporaryFile(
    scoped_refptr<base::SequencedTaskRunner> file_task_runner) {
}

void TestURLFetcher::SaveResponseWithWriter(
    scoped_ptr<URLFetcherResponseWriter> response_writer) {
  // In class URLFetcherCore this method is called by all three:
  // GetResponseAsString() / SaveResponseToFileAtPath() /
  // SaveResponseToTemporaryFile(). But here (in TestURLFetcher), this method
  // is never used by any of these three methods. So, file writing is expected
  // to be done in SaveResponseToFileAtPath(), and this method supports only
  // URLFetcherStringWriter (for testing of this method only).
  if (fake_response_destination_ == STRING) {
    response_writer_ = response_writer.Pass();
    int response = response_writer_->Initialize(CompletionCallback());
    // The TestURLFetcher doesn't handle asynchronous writes.
    DCHECK_EQ(OK, response);

    scoped_refptr<IOBuffer> buffer(new StringIOBuffer(fake_response_string_));
    response = response_writer_->Write(buffer.get(),
                                       fake_response_string_.size(),
                                       CompletionCallback());
    DCHECK_EQ(static_cast<int>(fake_response_string_.size()), response);
    response = response_writer_->Finish(CompletionCallback());
    DCHECK_EQ(OK, response);
  } else if (fake_response_destination_ == TEMP_FILE) {
    // SaveResponseToFileAtPath() should be called instead of this method to
    // save file. Asynchronous file writing using URLFetcherFileWriter is not
    // supported.
    NOTIMPLEMENTED();
  } else {
    NOTREACHED();
  }
}

HttpResponseHeaders* TestURLFetcher::GetResponseHeaders() const {
  return fake_response_headers_.get();
}

HostPortPair TestURLFetcher::GetSocketAddress() const {
  NOTIMPLEMENTED();
  return HostPortPair();
}

bool TestURLFetcher::WasFetchedViaProxy() const {
  return fake_was_fetched_via_proxy_;
}

void TestURLFetcher::Start() {
  // Overriden to do nothing. It is assumed the caller will notify the delegate.
  if (delegate_for_tests_)
    delegate_for_tests_->OnRequestStart(id_);
}

const GURL& TestURLFetcher::GetOriginalURL() const {
  return original_url_;
}

const GURL& TestURLFetcher::GetURL() const {
  return fake_url_;
}

const URLRequestStatus& TestURLFetcher::GetStatus() const {
  return fake_status_;
}

int TestURLFetcher::GetResponseCode() const {
  return fake_response_code_;
}

const ResponseCookies& TestURLFetcher::GetCookies() const {
  return fake_cookies_;
}

void TestURLFetcher::ReceivedContentWasMalformed() {
}

bool TestURLFetcher::GetResponseAsString(
    std::string* out_response_string) const {
  if (fake_response_destination_ != STRING)
    return false;

  *out_response_string = fake_response_string_;
  return true;
}

bool TestURLFetcher::GetResponseAsFilePath(
    bool take_ownership, base::FilePath* out_response_path) const {
  if (fake_response_destination_ != TEMP_FILE)
    return false;

  *out_response_path = fake_response_file_path_;
  return true;
}

void TestURLFetcher::GetExtraRequestHeaders(
    HttpRequestHeaders* headers) const {
  *headers = fake_extra_request_headers_;
}

void TestURLFetcher::set_status(const URLRequestStatus& status) {
  fake_status_ = status;
}

void TestURLFetcher::set_was_fetched_via_proxy(bool flag) {
  fake_was_fetched_via_proxy_ = flag;
}

void TestURLFetcher::set_response_headers(
    scoped_refptr<HttpResponseHeaders> headers) {
  fake_response_headers_ = headers;
}

void TestURLFetcher::set_backoff_delay(base::TimeDelta backoff_delay) {
  fake_backoff_delay_ = backoff_delay;
}

void TestURLFetcher::SetDelegateForTests(DelegateForTests* delegate_for_tests) {
  delegate_for_tests_ = delegate_for_tests;
}

void TestURLFetcher::SetResponseString(const std::string& response) {
  fake_response_destination_ = STRING;
  fake_response_string_ = response;
}

void TestURLFetcher::SetResponseFilePath(const base::FilePath& path) {
  fake_response_destination_ = TEMP_FILE;
  fake_response_file_path_ = path;
}

TestURLFetcherFactory::TestURLFetcherFactory()
    : ScopedURLFetcherFactory(this),
      delegate_for_tests_(NULL),
      remove_fetcher_on_delete_(false) {
}

TestURLFetcherFactory::~TestURLFetcherFactory() {}

URLFetcher* TestURLFetcherFactory::CreateURLFetcher(
    int id,
    const GURL& url,
    URLFetcher::RequestType request_type,
    URLFetcherDelegate* d) {
  TestURLFetcher* fetcher = new TestURLFetcher(id, url, d);
  if (remove_fetcher_on_delete_)
    fetcher->set_owner(this);
  fetcher->SetDelegateForTests(delegate_for_tests_);
  fetchers_[id] = fetcher;
  return fetcher;
}

TestURLFetcher* TestURLFetcherFactory::GetFetcherByID(int id) const {
  Fetchers::const_iterator i = fetchers_.find(id);
  return i == fetchers_.end() ? NULL : i->second;
}

void TestURLFetcherFactory::RemoveFetcherFromMap(int id) {
  Fetchers::iterator i = fetchers_.find(id);
  DCHECK(i != fetchers_.end());
  fetchers_.erase(i);
}

void TestURLFetcherFactory::SetDelegateForTests(
    TestURLFetcherDelegateForTests* delegate_for_tests) {
  delegate_for_tests_ = delegate_for_tests;
}

FakeURLFetcher::FakeURLFetcher(const GURL& url,
                               URLFetcherDelegate* d,
                               const std::string& response_data,
                               HttpStatusCode response_code,
                               URLRequestStatus::Status status)
    : TestURLFetcher(0, url, d),
      weak_factory_(this) {
  Error error = OK;
  switch(status) {
    case URLRequestStatus::SUCCESS:
      // |error| is initialized to OK.
      break;
    case URLRequestStatus::IO_PENDING:
      error = ERR_IO_PENDING;
      break;
    case URLRequestStatus::CANCELED:
      error = ERR_ABORTED;
      break;
    case URLRequestStatus::FAILED:
      error = ERR_FAILED;
      break;
  }
  set_status(URLRequestStatus(status, error));
  set_response_code(response_code);
  SetResponseString(response_data);
}

FakeURLFetcher::~FakeURLFetcher() {}

void FakeURLFetcher::Start() {
  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&FakeURLFetcher::RunDelegate, weak_factory_.GetWeakPtr()));
}

void FakeURLFetcher::RunDelegate() {
  delegate()->OnURLFetchComplete(this);
}

const GURL& FakeURLFetcher::GetURL() const {
  return TestURLFetcher::GetOriginalURL();
}

FakeURLFetcherFactory::FakeURLFetcherFactory(
    URLFetcherFactory* default_factory)
    : ScopedURLFetcherFactory(this),
      creator_(base::Bind(&DefaultFakeURLFetcherCreator)),
      default_factory_(default_factory) {
}

FakeURLFetcherFactory::FakeURLFetcherFactory(
    URLFetcherFactory* default_factory,
    const FakeURLFetcherCreator& creator)
    : ScopedURLFetcherFactory(this),
      creator_(creator),
      default_factory_(default_factory) {
}

scoped_ptr<FakeURLFetcher> FakeURLFetcherFactory::DefaultFakeURLFetcherCreator(
      const GURL& url,
      URLFetcherDelegate* delegate,
      const std::string& response_data,
      HttpStatusCode response_code,
      URLRequestStatus::Status status) {
  return scoped_ptr<FakeURLFetcher>(
      new FakeURLFetcher(url, delegate, response_data, response_code, status));
}

FakeURLFetcherFactory::~FakeURLFetcherFactory() {}

URLFetcher* FakeURLFetcherFactory::CreateURLFetcher(
    int id,
    const GURL& url,
    URLFetcher::RequestType request_type,
    URLFetcherDelegate* d) {
  FakeResponseMap::const_iterator it = fake_responses_.find(url);
  if (it == fake_responses_.end()) {
    if (default_factory_ == NULL) {
      // If we don't have a baked response for that URL we return NULL.
      DLOG(ERROR) << "No baked response for URL: " << url.spec();
      return NULL;
    } else {
      return default_factory_->CreateURLFetcher(id, url, request_type, d);
    }
  }

  scoped_ptr<FakeURLFetcher> fake_fetcher =
      creator_.Run(url, d, it->second.response_data,
                   it->second.response_code, it->second.status);
  // TODO: Make URLFetcherFactory::CreateURLFetcher return a scoped_ptr
  return fake_fetcher.release();
}

void FakeURLFetcherFactory::SetFakeResponse(
    const GURL& url,
    const std::string& response_data,
    HttpStatusCode response_code,
    URLRequestStatus::Status status) {
  // Overwrite existing URL if it already exists.
  FakeURLResponse response;
  response.response_data = response_data;
  response.response_code = response_code;
  response.status = status;
  fake_responses_[url] = response;
}

void FakeURLFetcherFactory::ClearFakeResponses() {
  fake_responses_.clear();
}

URLFetcherImplFactory::URLFetcherImplFactory() {}

URLFetcherImplFactory::~URLFetcherImplFactory() {}

URLFetcher* URLFetcherImplFactory::CreateURLFetcher(
    int id,
    const GURL& url,
    URLFetcher::RequestType request_type,
    URLFetcherDelegate* d) {
  return new URLFetcherImpl(url, request_type, d);
}

}  // namespace net
