// 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 "mojo/services/html_viewer/weburlloader_impl.h"

#include "base/bind.h"
#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/thread_task_runner_handle.h"
#include "mojo/common/common_type_converters.h"
#include "mojo/services/html_viewer/blink_url_request_type_converters.h"
#include "mojo/services/public/interfaces/network/network_service.mojom.h"
#include "net/base/net_errors.h"
#include "third_party/WebKit/public/platform/WebURLError.h"
#include "third_party/WebKit/public/platform/WebURLLoadTiming.h"
#include "third_party/WebKit/public/platform/WebURLLoaderClient.h"
#include "third_party/WebKit/public/platform/WebURLResponse.h"

namespace mojo {
namespace {

static blink::WebURLResponse::HTTPVersion StatusLineToHTTPVersion(
    const String& status_line) {
  if (status_line.is_null())
    return blink::WebURLResponse::HTTP_0_9;

  if (StartsWithASCII(status_line, "HTTP/1.0", true))
    return blink::WebURLResponse::HTTP_1_0;

  if (StartsWithASCII(status_line, "HTTP/1.1", true))
    return blink::WebURLResponse::HTTP_1_1;

  return blink::WebURLResponse::Unknown;
}

blink::WebURLResponse ToWebURLResponse(const URLResponsePtr& url_response) {
  blink::WebURLResponse result;
  result.initialize();
  result.setURL(GURL(url_response->url));
  result.setMIMEType(blink::WebString::fromUTF8(url_response->mime_type));
  result.setTextEncodingName(blink::WebString::fromUTF8(url_response->charset));
  result.setHTTPVersion(StatusLineToHTTPVersion(url_response->status_line));
  result.setHTTPStatusCode(url_response->status_code);

  // TODO(darin): Initialize timing properly.
  blink::WebURLLoadTiming timing;
  timing.initialize();
  result.setLoadTiming(timing);

  for (size_t i = 0; i < url_response->headers.size(); ++i) {
    const std::string& header_line = url_response->headers[i];
    size_t first_colon = header_line.find(":");

    if (first_colon == std::string::npos || first_colon == 0)
      continue;

    std::string value;
    TrimWhitespaceASCII(header_line.substr(first_colon + 1),
                        base::TRIM_LEADING,
                        &value);
    result.setHTTPHeaderField(
        blink::WebString::fromUTF8(header_line.substr(0, first_colon)),
        blink::WebString::fromUTF8(value));
  }

  return result;
}

}  // namespace

WebURLRequestExtraData::WebURLRequestExtraData() {
}

WebURLRequestExtraData::~WebURLRequestExtraData() {
}

WebURLLoaderImpl::WebURLLoaderImpl(NetworkService* network_service)
    : client_(NULL),
      weak_factory_(this) {
  network_service->CreateURLLoader(GetProxy(&url_loader_));
}

WebURLLoaderImpl::~WebURLLoaderImpl() {
}

void WebURLLoaderImpl::loadSynchronously(
    const blink::WebURLRequest& request,
    blink::WebURLResponse& response,
    blink::WebURLError& error,
    blink::WebData& data) {
  NOTIMPLEMENTED();
}

void WebURLLoaderImpl::loadAsynchronously(const blink::WebURLRequest& request,
                                          blink::WebURLLoaderClient* client) {
  client_ = client;
  url_ = request.url();

  URLRequestPtr url_request = URLRequest::From(request);
  url_request->auto_follow_redirects = false;

  if (request.extraData()) {
    WebURLRequestExtraData* extra_data =
        static_cast<WebURLRequestExtraData*>(request.extraData());
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE,
        base::Bind(&WebURLLoaderImpl::OnReceivedResponse,
                   weak_factory_.GetWeakPtr(),
                   base::Passed(&extra_data->synthetic_response)));
  } else {
    url_loader_->Start(url_request.Pass(),
                       base::Bind(&WebURLLoaderImpl::OnReceivedResponse,
                                  weak_factory_.GetWeakPtr()));
  }
}

void WebURLLoaderImpl::cancel() {
  url_loader_.reset();
  response_body_stream_.reset();

  URLResponsePtr failed_response(URLResponse::New());
  failed_response->url = String::From(url_);
  failed_response->error = NetworkError::New();
  failed_response->error->code = net::ERR_ABORTED;

  base::ThreadTaskRunnerHandle::Get()->PostTask(
      FROM_HERE,
      base::Bind(&WebURLLoaderImpl::OnReceivedResponse,
                 weak_factory_.GetWeakPtr(),
                 base::Passed(&failed_response)));
}

void WebURLLoaderImpl::setDefersLoading(bool defers_loading) {
  NOTIMPLEMENTED();
}

void WebURLLoaderImpl::OnReceivedResponse(URLResponsePtr url_response) {
  url_ = GURL(url_response->url);

  if (url_response->error) {
    OnReceivedError(url_response.Pass());
  } else if (url_response->redirect_url) {
    OnReceivedRedirect(url_response.Pass());
  } else {
    base::WeakPtr<WebURLLoaderImpl> self(weak_factory_.GetWeakPtr());
    client_->didReceiveResponse(this, ToWebURLResponse(url_response));

    // We may have been deleted during didReceiveResponse.
    if (!self)
      return;

    // Start streaming data
    response_body_stream_ = url_response->body.Pass();
    ReadMore();
  }
}

void WebURLLoaderImpl::OnReceivedError(URLResponsePtr url_response) {
  blink::WebURLError web_error;
  web_error.domain = blink::WebString::fromUTF8(net::kErrorDomain);
  web_error.reason = url_response->error->code;
  web_error.unreachableURL = GURL(url_response->url);
  web_error.staleCopyInCache = false;
  web_error.isCancellation =
      url_response->error->code == net::ERR_ABORTED ? true : false;

  client_->didFail(this, web_error);
}

void WebURLLoaderImpl::OnReceivedRedirect(URLResponsePtr url_response) {
  blink::WebURLRequest new_request;
  new_request.initialize();
  new_request.setURL(GURL(url_response->redirect_url));
  new_request.setHTTPMethod(
      blink::WebString::fromUTF8(url_response->redirect_method));

  client_->willSendRequest(this, new_request, ToWebURLResponse(url_response));
  // TODO(darin): Check if new_request was rejected.

  url_loader_->FollowRedirect(
      base::Bind(&WebURLLoaderImpl::OnReceivedResponse,
                 weak_factory_.GetWeakPtr()));
}

void WebURLLoaderImpl::ReadMore() {
  const void* buf;
  uint32_t buf_size;
  MojoResult rv = BeginReadDataRaw(response_body_stream_.get(),
                                   &buf,
                                   &buf_size,
                                   MOJO_READ_DATA_FLAG_NONE);
  if (rv == MOJO_RESULT_OK) {
    client_->didReceiveData(this, static_cast<const char*>(buf), buf_size, -1);
    EndReadDataRaw(response_body_stream_.get(), buf_size);
    WaitToReadMore();
  } else if (rv == MOJO_RESULT_SHOULD_WAIT) {
    WaitToReadMore();
  } else if (rv == MOJO_RESULT_FAILED_PRECONDITION) {
    // We reached end-of-file.
    double finish_time = base::Time::Now().ToDoubleT();
    client_->didFinishLoading(
        this,
        finish_time,
        blink::WebURLLoaderClient::kUnknownEncodedDataLength);
  } else {
    // TODO(darin): Oops!
  }
}

void WebURLLoaderImpl::WaitToReadMore() {
  handle_watcher_.Start(
      response_body_stream_.get(),
      MOJO_HANDLE_SIGNAL_READABLE,
      MOJO_DEADLINE_INDEFINITE,
      base::Bind(&WebURLLoaderImpl::OnResponseBodyStreamReady,
                 weak_factory_.GetWeakPtr()));
}

void WebURLLoaderImpl::OnResponseBodyStreamReady(MojoResult result) {
  ReadMore();
}

}  // namespace mojo
