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

#include "base/command_line.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/loader/global_routing_id.h"
#include "content/browser/loader/resource_message_filter.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/net/url_request_user_data.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
#include "net/url_request/url_request.h"

namespace content {

namespace {

WebContents* GetWebContentsFromFTNID(int frame_tree_node_id) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  FrameTreeNode* frame_tree_node =
      FrameTreeNode::GloballyFindByID(frame_tree_node_id);
  if (!frame_tree_node)
    return nullptr;

  return WebContentsImpl::FromFrameTreeNode(frame_tree_node);
}

}  // namespace

// ----------------------------------------------------------------------------
// ResourceRequestInfo

// static
const ResourceRequestInfo* ResourceRequestInfo::ForRequest(
    const net::URLRequest* request) {
  return ResourceRequestInfoImpl::ForRequest(request);
}

// static
void ResourceRequestInfo::AllocateForTesting(net::URLRequest* request,
                                             ResourceType resource_type,
                                             ResourceContext* context,
                                             int render_process_id,
                                             int render_view_id,
                                             int render_frame_id,
                                             bool is_main_frame,
                                             bool parent_is_main_frame,
                                             bool allow_download,
                                             bool is_async,
                                             bool is_using_lofi) {
  // Make sure both |is_main_frame| and |parent_is_main_frame| aren't set at the
  // same time.
  DCHECK(!(is_main_frame && parent_is_main_frame));

  // Make sure RESOURCE_TYPE_MAIN_FRAME is declared as being fetched as part of
  // the main frame.
  DCHECK(resource_type != RESOURCE_TYPE_MAIN_FRAME || is_main_frame);

  ResourceRequestInfoImpl* info =
      new ResourceRequestInfoImpl(
          PROCESS_TYPE_RENDERER,             // process_type
          render_process_id,                 // child_id
          render_view_id,                    // route_id
          -1,                                // frame_tree_node_id
          0,                                 // origin_pid
          0,                                 // request_id
          render_frame_id,                   // render_frame_id
          is_main_frame,                     // is_main_frame
          parent_is_main_frame,              // parent_is_main_frame
          0,                                 // parent_render_frame_id
          resource_type,                     // resource_type
          ui::PAGE_TRANSITION_LINK,          // transition_type
          false,                             // should_replace_current_entry
          false,                             // is_download
          false,                             // is_stream
          allow_download,                    // allow_download
          false,                             // has_user_gesture
          false,                             // enable load timing
          request->has_upload(),             // enable upload progress
          false,                             // do_not_prompt_for_login
          blink::WebReferrerPolicyDefault,   // referrer_policy
          blink::WebPageVisibilityStateVisible,  // visibility_state
          context,                           // context
          base::WeakPtr<ResourceMessageFilter>(),  // filter
          false,                             // report_raw_headers
          is_async,                          // is_async
          is_using_lofi);                    // is_using_lofi
  info->AssociateWithRequest(request);
}

// static
bool ResourceRequestInfo::GetRenderFrameForRequest(
    const net::URLRequest* request,
    int* render_process_id,
    int* render_frame_id) {
  URLRequestUserData* user_data = static_cast<URLRequestUserData*>(
      request->GetUserData(URLRequestUserData::kUserDataKey));
  if (!user_data)
    return false;
  *render_process_id = user_data->render_process_id();
  *render_frame_id = user_data->render_frame_id();
  return true;
}

// ----------------------------------------------------------------------------
// ResourceRequestInfoImpl

// static
ResourceRequestInfoImpl* ResourceRequestInfoImpl::ForRequest(
    net::URLRequest* request) {
  return static_cast<ResourceRequestInfoImpl*>(request->GetUserData(NULL));
}

// static
const ResourceRequestInfoImpl* ResourceRequestInfoImpl::ForRequest(
    const net::URLRequest* request) {
  return ForRequest(const_cast<net::URLRequest*>(request));
}

ResourceRequestInfoImpl::ResourceRequestInfoImpl(
    int process_type,
    int child_id,
    int route_id,
    int frame_tree_node_id,
    int origin_pid,
    int request_id,
    int render_frame_id,
    bool is_main_frame,
    bool parent_is_main_frame,
    int parent_render_frame_id,
    ResourceType resource_type,
    ui::PageTransition transition_type,
    bool should_replace_current_entry,
    bool is_download,
    bool is_stream,
    bool allow_download,
    bool has_user_gesture,
    bool enable_load_timing,
    bool enable_upload_progress,
    bool do_not_prompt_for_login,
    blink::WebReferrerPolicy referrer_policy,
    blink::WebPageVisibilityState visibility_state,
    ResourceContext* context,
    base::WeakPtr<ResourceMessageFilter> filter,
    bool report_raw_headers,
    bool is_async,
    bool is_using_lofi)
    : cross_site_handler_(NULL),
      detachable_handler_(NULL),
      process_type_(process_type),
      child_id_(child_id),
      route_id_(route_id),
      frame_tree_node_id_(frame_tree_node_id),
      origin_pid_(origin_pid),
      request_id_(request_id),
      render_frame_id_(render_frame_id),
      is_main_frame_(is_main_frame),
      parent_is_main_frame_(parent_is_main_frame),
      parent_render_frame_id_(parent_render_frame_id),
      should_replace_current_entry_(should_replace_current_entry),
      is_download_(is_download),
      is_stream_(is_stream),
      allow_download_(allow_download),
      has_user_gesture_(has_user_gesture),
      enable_load_timing_(enable_load_timing),
      enable_upload_progress_(enable_upload_progress),
      do_not_prompt_for_login_(do_not_prompt_for_login),
      was_ignored_by_handler_(false),
      counted_as_in_flight_request_(false),
      resource_type_(resource_type),
      transition_type_(transition_type),
      memory_cost_(0),
      referrer_policy_(referrer_policy),
      visibility_state_(visibility_state),
      context_(context),
      filter_(filter),
      report_raw_headers_(report_raw_headers),
      is_async_(is_async),
      is_using_lofi_(is_using_lofi) {
}

ResourceRequestInfoImpl::~ResourceRequestInfoImpl() {
}

ResourceRequestInfo::WebContentsGetter
ResourceRequestInfoImpl::GetWebContentsGetterForRequest() const {
  // PlzNavigate: navigation requests are created with a valid FrameTreeNode ID
  // and invalid RenderProcessHost and RenderFrameHost IDs. The FrameTreeNode
  // ID should be used to access the WebContents.
  if (frame_tree_node_id_ != -1) {
    DCHECK(base::CommandLine::ForCurrentProcess()->HasSwitch(
        switches::kEnableBrowserSideNavigation));
    return base::Bind(&GetWebContentsFromFTNID, frame_tree_node_id_);
  }

  // In other cases, use the RenderProcessHost ID + RenderFrameHost ID to get
  // the WebContents.
  int render_process_host_id = -1;
  int render_frame_host_id = -1;
  if (!GetAssociatedRenderFrame(&render_process_host_id,
                                &render_frame_host_id)) {
    NOTREACHED();
  }

  return base::Bind(&WebContentsImpl::FromRenderFrameHostID,
                    render_process_host_id, render_frame_host_id);
}

ResourceContext* ResourceRequestInfoImpl::GetContext() const {
  return context_;
}

int ResourceRequestInfoImpl::GetChildID() const {
  return child_id_;
}

int ResourceRequestInfoImpl::GetRouteID() const {
  return route_id_;
}

int ResourceRequestInfoImpl::GetOriginPID() const {
  return origin_pid_;
}

int ResourceRequestInfoImpl::GetRenderFrameID() const {
  return render_frame_id_;
}

bool ResourceRequestInfoImpl::IsMainFrame() const {
  return is_main_frame_;
}

bool ResourceRequestInfoImpl::ParentIsMainFrame() const {
  return parent_is_main_frame_;
}

int ResourceRequestInfoImpl::GetParentRenderFrameID() const {
  return parent_render_frame_id_;
}

ResourceType ResourceRequestInfoImpl::GetResourceType() const {
  return resource_type_;
}

int ResourceRequestInfoImpl::GetProcessType() const {
  return process_type_;
}

blink::WebReferrerPolicy ResourceRequestInfoImpl::GetReferrerPolicy() const {
  return referrer_policy_;
}

blink::WebPageVisibilityState
ResourceRequestInfoImpl::GetVisibilityState() const {
  return visibility_state_;
}

ui::PageTransition ResourceRequestInfoImpl::GetPageTransition() const {
  return transition_type_;
}

bool ResourceRequestInfoImpl::HasUserGesture() const {
  return has_user_gesture_;
}

bool ResourceRequestInfoImpl::WasIgnoredByHandler() const {
  return was_ignored_by_handler_;
}

bool ResourceRequestInfoImpl::GetAssociatedRenderFrame(
    int* render_process_id,
    int* render_frame_id) const {
  if (process_type_ == PROCESS_TYPE_PLUGIN) {
    *render_process_id = origin_pid_;
    *render_frame_id = render_frame_id_;
  } else {
    *render_process_id = child_id_;
    *render_frame_id = render_frame_id_;
  }
  return true;
}

bool ResourceRequestInfoImpl::IsAsync() const {
  return is_async_;
}

bool ResourceRequestInfoImpl::IsDownload() const {
  return is_download_;
}

bool ResourceRequestInfoImpl::IsUsingLoFi() const {
  return is_using_lofi_;
}

bool ResourceRequestInfoImpl::ShouldReportRawHeaders() const {
  return report_raw_headers_;
}

void ResourceRequestInfoImpl::AssociateWithRequest(net::URLRequest* request) {
  request->SetUserData(NULL, this);
  int render_process_id;
  int render_frame_id;
  if (GetAssociatedRenderFrame(&render_process_id, &render_frame_id)) {
    request->SetUserData(
        URLRequestUserData::kUserDataKey,
        new URLRequestUserData(render_process_id, render_frame_id));
  }
}

int ResourceRequestInfoImpl::GetRequestID() const {
  return request_id_;
}

GlobalRequestID ResourceRequestInfoImpl::GetGlobalRequestID() const {
  return GlobalRequestID(child_id_, request_id_);
}

GlobalRoutingID ResourceRequestInfoImpl::GetGlobalRoutingID() const {
  return GlobalRoutingID(child_id_, route_id_);
}

void ResourceRequestInfoImpl::UpdateForTransfer(
    int child_id,
    int route_id,
    int origin_pid,
    int request_id,
    int parent_render_frame_id,
    base::WeakPtr<ResourceMessageFilter> filter) {
  child_id_ = child_id;
  route_id_ = route_id;
  origin_pid_ = origin_pid;
  request_id_ = request_id;
  parent_render_frame_id_ = parent_render_frame_id;
  filter_ = filter;
}

}  // namespace content
