// 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 "content/browser/loader/navigation_resource_handler.h"

#include <memory>

#include "base/logging.h"
#include "content/browser/loader/navigation_url_loader_impl_core.h"
#include "content/browser/loader/netlog_observer.h"
#include "content/browser/loader/resource_request_info_impl.h"
#include "content/browser/resource_context_impl.h"
#include "content/browser/streams/stream.h"
#include "content/browser/streams/stream_context.h"
#include "content/public/browser/navigation_data.h"
#include "content/public/browser/resource_controller.h"
#include "content/public/browser/resource_dispatcher_host_delegate.h"
#include "content/public/browser/stream_handle.h"
#include "content/public/common/resource_response.h"
#include "net/base/net_errors.h"
#include "net/url_request/url_request.h"

namespace content {

NavigationResourceHandler::NavigationResourceHandler(
    net::URLRequest* request,
    NavigationURLLoaderImplCore* core,
    ResourceDispatcherHostDelegate* resource_dispatcher_host_delegate)
    : ResourceHandler(request),
      core_(core),
      resource_dispatcher_host_delegate_(resource_dispatcher_host_delegate) {
  core_->set_resource_handler(this);
  writer_.set_immediate_mode(true);
}

NavigationResourceHandler::~NavigationResourceHandler() {
  if (core_) {
    core_->NotifyRequestFailed(false, net::ERR_ABORTED);
    DetachFromCore();
  }
}

void NavigationResourceHandler::Cancel() {
  controller()->Cancel();
  core_ = nullptr;
}

void NavigationResourceHandler::FollowRedirect() {
  controller()->Resume();
}

void NavigationResourceHandler::ProceedWithResponse() {
  // Detach from the loader; at this point, the request is now owned by the
  // StreamHandle sent in OnResponseStarted.
  DetachFromCore();
  controller()->Resume();
}

void NavigationResourceHandler::SetController(ResourceController* controller) {
  writer_.set_controller(controller);
  ResourceHandler::SetController(controller);
}

bool NavigationResourceHandler::OnRequestRedirected(
    const net::RedirectInfo& redirect_info,
    ResourceResponse* response,
    bool* defer) {
  DCHECK(core_);

  // TODO(davidben): Perform a CSP check here, and anything else that would have
  // been done renderer-side.
  NetLogObserver::PopulateResponseInfo(request(), response);
  core_->NotifyRequestRedirected(redirect_info, response);
  *defer = true;
  return true;
}

bool NavigationResourceHandler::OnResponseStarted(ResourceResponse* response,
                                                  bool* defer) {
  DCHECK(core_);

  ResourceRequestInfoImpl* info = GetRequestInfo();

  // If the MimeTypeResourceHandler intercepted this request and converted it
  // into a download, it will still call OnResponseStarted and immediately
  // cancel. Ignore the call; OnReadCompleted will happen shortly.
  //
  // TODO(davidben): Move the dispatch out of MimeTypeResourceHandler. Perhaps
  // all the way to the UI thread. Downloads, user certificates, etc., should be
  // dispatched at the navigation layer.
  if (info->IsDownload() || info->is_stream())
    return true;

  StreamContext* stream_context =
      GetStreamContextForResourceContext(info->GetContext());
  writer_.InitializeStream(stream_context->registry(),
                           request()->url().GetOrigin());

  NetLogObserver::PopulateResponseInfo(request(), response);

  std::unique_ptr<NavigationData> cloned_data;
  if (resource_dispatcher_host_delegate_) {
    // Ask the embedder for a NavigationData instance.
    NavigationData* navigation_data =
        resource_dispatcher_host_delegate_->GetNavigationData(request());

    // Clone the embedder's NavigationData before moving it to the UI thread.
    if (navigation_data)
      cloned_data = navigation_data->Clone();
  }

  core_->NotifyResponseStarted(response, writer_.stream()->CreateHandle(),
                               std::move(cloned_data));
  *defer = true;

  return true;
}

bool NavigationResourceHandler::OnWillStart(const GURL& url, bool* defer) {
  return true;
}

bool NavigationResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
                                           int* buf_size,
                                           int min_size) {
  writer_.OnWillRead(buf, buf_size, min_size);
  return true;
}

bool NavigationResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
  writer_.OnReadCompleted(bytes_read, defer);
  return true;
}

void NavigationResourceHandler::OnResponseCompleted(
    const net::URLRequestStatus& status,
    const std::string& security_info,
    bool* defer) {
  // If the request has already committed, close the stream and leave it as-is.
  //
  // TODO(davidben): The net error code should be passed through StreamWriter
  // down to the stream's consumer. See https://crbug.com/426162.
  if (writer_.stream()) {
    writer_.Finalize();
    return;
  }

  if (core_) {
    DCHECK_NE(net::OK, status.error());
    core_->NotifyRequestFailed(request()->response_info().was_cached,
                               status.error());
    DetachFromCore();
  }
}

void NavigationResourceHandler::OnDataDownloaded(int bytes_downloaded) {
  NOTREACHED();
}

void NavigationResourceHandler::DetachFromCore() {
  DCHECK(core_);
  core_->set_resource_handler(nullptr);
  core_ = nullptr;
}

}  // namespace content
