// Copyright 2013 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/frame_host/navigation_entry_impl.h"

#include <queue>

#include "base/metrics/histogram.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "content/common/navigation_params.h"
#include "content/public/common/content_constants.h"
#include "content/public/common/url_constants.h"
#include "net/base/net_util.h"
#include "ui/gfx/text_elider.h"

// Use this to get a new unique ID for a NavigationEntry during construction.
// The returned ID is guaranteed to be nonzero (which is the "no ID" indicator).
static int GetUniqueIDInConstructor() {
  static int unique_id_counter = 0;
  return ++unique_id_counter;
}

namespace content {

int NavigationEntryImpl::kInvalidBindings = -1;

NavigationEntryImpl::TreeNode::TreeNode(FrameNavigationEntry* frame_entry)
    : frame_entry(frame_entry) {
}

NavigationEntryImpl::TreeNode::~TreeNode() {
}

bool NavigationEntryImpl::TreeNode::MatchesFrame(
    FrameTreeNode* frame_tree_node) const {
  if (frame_tree_node->frame_tree_node_id() ==
      frame_entry->frame_tree_node_id())
    return true;

  // For now, we set the root FNE's FrameTreeNode ID to -1.
  return frame_tree_node->IsMainFrame() &&
         frame_entry->frame_tree_node_id() == -1;
}

scoped_ptr<NavigationEntryImpl::TreeNode>
NavigationEntryImpl::TreeNode::CloneAndReplace(
    FrameTreeNode* frame_tree_node,
    FrameNavigationEntry* frame_navigation_entry) const {
  if (frame_tree_node && MatchesFrame(frame_tree_node)) {
    // Replace this node in the cloned tree and prune its children.
    return make_scoped_ptr(
        new NavigationEntryImpl::TreeNode(frame_navigation_entry));
  }

  // Clone the tree using a copy of the FrameNavigationEntry, without sharing.
  // TODO(creis): Share FNEs unless it's for another tab.
  scoped_ptr<NavigationEntryImpl::TreeNode> copy(
      new NavigationEntryImpl::TreeNode(frame_entry->Clone()));

  // Recursively clone the children.
  for (auto& child : children) {
    copy->children.push_back(
        child->CloneAndReplace(frame_tree_node, frame_navigation_entry));
  }

  return copy.Pass();
}

NavigationEntry* NavigationEntry::Create() {
  return new NavigationEntryImpl();
}

NavigationEntryImpl* NavigationEntryImpl::FromNavigationEntry(
    NavigationEntry* entry) {
  return static_cast<NavigationEntryImpl*>(entry);
}

const NavigationEntryImpl* NavigationEntryImpl::FromNavigationEntry(
    const NavigationEntry* entry) {
  return static_cast<const NavigationEntryImpl*>(entry);
}

NavigationEntryImpl::NavigationEntryImpl()
    : NavigationEntryImpl(nullptr, -1, GURL(), Referrer(), base::string16(),
                          ui::PAGE_TRANSITION_LINK, false) {
}

NavigationEntryImpl::NavigationEntryImpl(SiteInstanceImpl* instance,
                                         int page_id,
                                         const GURL& url,
                                         const Referrer& referrer,
                                         const base::string16& title,
                                         ui::PageTransition transition_type,
                                         bool is_renderer_initiated)
    : frame_tree_(
          new TreeNode(new FrameNavigationEntry(-1, instance, url, referrer))),
      unique_id_(GetUniqueIDInConstructor()),
      bindings_(kInvalidBindings),
      page_type_(PAGE_TYPE_NORMAL),
      update_virtual_url_with_url_(false),
      title_(title),
      page_id_(page_id),
      transition_type_(transition_type),
      has_post_data_(false),
      post_id_(-1),
      restore_type_(RESTORE_NONE),
      is_overriding_user_agent_(false),
      http_status_code_(0),
      is_renderer_initiated_(is_renderer_initiated),
      should_replace_entry_(false),
      should_clear_history_list_(false),
      can_load_local_resources_(false),
      frame_tree_node_id_(-1) {
}

NavigationEntryImpl::~NavigationEntryImpl() {
}

int NavigationEntryImpl::GetUniqueID() const {
  return unique_id_;
}

PageType NavigationEntryImpl::GetPageType() const {
  return page_type_;
}

void NavigationEntryImpl::SetURL(const GURL& url) {
  frame_tree_->frame_entry->set_url(url);
  cached_display_title_.clear();
}

const GURL& NavigationEntryImpl::GetURL() const {
  return frame_tree_->frame_entry->url();
}

void NavigationEntryImpl::SetBaseURLForDataURL(const GURL& url) {
  base_url_for_data_url_ = url;
}

const GURL& NavigationEntryImpl::GetBaseURLForDataURL() const {
  return base_url_for_data_url_;
}

void NavigationEntryImpl::SetReferrer(const Referrer& referrer) {
  frame_tree_->frame_entry->set_referrer(referrer);
}

const Referrer& NavigationEntryImpl::GetReferrer() const {
  return frame_tree_->frame_entry->referrer();
}

void NavigationEntryImpl::SetVirtualURL(const GURL& url) {
  virtual_url_ = (url == GetURL()) ? GURL() : url;
  cached_display_title_.clear();
}

const GURL& NavigationEntryImpl::GetVirtualURL() const {
  return virtual_url_.is_empty() ? GetURL() : virtual_url_;
}

void NavigationEntryImpl::SetTitle(const base::string16& title) {
  title_ = title;
  cached_display_title_.clear();
}

const base::string16& NavigationEntryImpl::GetTitle() const {
  return title_;
}

void NavigationEntryImpl::SetPageState(const PageState& state) {
  frame_tree_->frame_entry->set_page_state(state);
}

const PageState& NavigationEntryImpl::GetPageState() const {
  return frame_tree_->frame_entry->page_state();
}

void NavigationEntryImpl::SetPageID(int page_id) {
  page_id_ = page_id;
}

int32 NavigationEntryImpl::GetPageID() const {
  return page_id_;
}

void NavigationEntryImpl::set_site_instance(SiteInstanceImpl* site_instance) {
  // TODO(creis): Update all callers and remove this method.
  frame_tree_->frame_entry->set_site_instance(site_instance);
}

void NavigationEntryImpl::set_source_site_instance(
    SiteInstanceImpl* source_site_instance) {
  source_site_instance_ = source_site_instance;
}

void NavigationEntryImpl::SetBindings(int bindings) {
  // Ensure this is set to a valid value, and that it stays the same once set.
  CHECK_NE(bindings, kInvalidBindings);
  CHECK(bindings_ == kInvalidBindings || bindings_ == bindings);
  bindings_ = bindings;
}

const base::string16& NavigationEntryImpl::GetTitleForDisplay(
    const std::string& languages) const {
  // Most pages have real titles. Don't even bother caching anything if this is
  // the case.
  if (!title_.empty())
    return title_;

  // More complicated cases will use the URLs as the title. This result we will
  // cache since it's more complicated to compute.
  if (!cached_display_title_.empty())
    return cached_display_title_;

  // Use the virtual URL first if any, and fall back on using the real URL.
  base::string16 title;
  if (!virtual_url_.is_empty()) {
    title = net::FormatUrl(virtual_url_, languages);
  } else if (!GetURL().is_empty()) {
    title = net::FormatUrl(GetURL(), languages);
  }

  // For file:// URLs use the filename as the title, not the full path.
  if (GetURL().SchemeIsFile()) {
    base::string16::size_type slashpos = title.rfind('/');
    if (slashpos != base::string16::npos)
      title = title.substr(slashpos + 1);
  }

  gfx::ElideString(title, kMaxTitleChars, &cached_display_title_);
  return cached_display_title_;
}

bool NavigationEntryImpl::IsViewSourceMode() const {
  return virtual_url_.SchemeIs(kViewSourceScheme);
}

void NavigationEntryImpl::SetTransitionType(
    ui::PageTransition transition_type) {
  transition_type_ = transition_type;
}

ui::PageTransition NavigationEntryImpl::GetTransitionType() const {
  return transition_type_;
}

const GURL& NavigationEntryImpl::GetUserTypedURL() const {
  return user_typed_url_;
}

void NavigationEntryImpl::SetHasPostData(bool has_post_data) {
  has_post_data_ = has_post_data;
}

bool NavigationEntryImpl::GetHasPostData() const {
  return has_post_data_;
}

void NavigationEntryImpl::SetPostID(int64 post_id) {
  post_id_ = post_id;
}

int64 NavigationEntryImpl::GetPostID() const {
  return post_id_;
}

void NavigationEntryImpl::SetBrowserInitiatedPostData(
    const base::RefCountedMemory* data) {
  browser_initiated_post_data_ = data;
}

const base::RefCountedMemory*
NavigationEntryImpl::GetBrowserInitiatedPostData() const {
  return browser_initiated_post_data_.get();
}


const FaviconStatus& NavigationEntryImpl::GetFavicon() const {
  return favicon_;
}

FaviconStatus& NavigationEntryImpl::GetFavicon() {
  return favicon_;
}

const SSLStatus& NavigationEntryImpl::GetSSL() const {
  return ssl_;
}

SSLStatus& NavigationEntryImpl::GetSSL() {
  return ssl_;
}

void NavigationEntryImpl::SetOriginalRequestURL(const GURL& original_url) {
  original_request_url_ = original_url;
}

const GURL& NavigationEntryImpl::GetOriginalRequestURL() const {
  return original_request_url_;
}

void NavigationEntryImpl::SetIsOverridingUserAgent(bool override) {
  is_overriding_user_agent_ = override;
}

bool NavigationEntryImpl::GetIsOverridingUserAgent() const {
  return is_overriding_user_agent_;
}

void NavigationEntryImpl::SetTimestamp(base::Time timestamp) {
  timestamp_ = timestamp;
}

base::Time NavigationEntryImpl::GetTimestamp() const {
  return timestamp_;
}

void NavigationEntryImpl::SetHttpStatusCode(int http_status_code) {
  http_status_code_ = http_status_code;
}

int NavigationEntryImpl::GetHttpStatusCode() const {
  return http_status_code_;
}

void NavigationEntryImpl::SetRedirectChain(
    const std::vector<GURL>& redirect_chain) {
  redirect_chain_ = redirect_chain;
}

const std::vector<GURL>& NavigationEntryImpl::GetRedirectChain() const {
  return redirect_chain_;
}

bool NavigationEntryImpl::IsRestored() const {
  return restore_type_ != RESTORE_NONE;
}

void NavigationEntryImpl::SetCanLoadLocalResources(bool allow) {
  can_load_local_resources_ = allow;
}

bool NavigationEntryImpl::GetCanLoadLocalResources() const {
  return can_load_local_resources_;
}

void NavigationEntryImpl::SetExtraData(const std::string& key,
                                       const base::string16& data) {
  extra_data_[key] = data;
}

bool NavigationEntryImpl::GetExtraData(const std::string& key,
                                       base::string16* data) const {
  std::map<std::string, base::string16>::const_iterator iter =
      extra_data_.find(key);
  if (iter == extra_data_.end())
    return false;
  *data = iter->second;
  return true;
}

void NavigationEntryImpl::ClearExtraData(const std::string& key) {
  extra_data_.erase(key);
}

NavigationEntryImpl* NavigationEntryImpl::Clone() const {
  return NavigationEntryImpl::CloneAndReplace(nullptr, nullptr);
}

NavigationEntryImpl* NavigationEntryImpl::CloneAndReplace(
    FrameTreeNode* frame_tree_node,
    FrameNavigationEntry* frame_navigation_entry) const {
  NavigationEntryImpl* copy = new NavigationEntryImpl();

  // TODO(creis): Only share the same FrameNavigationEntries if cloning within
  // the same tab.
  copy->frame_tree_ =
      frame_tree_->CloneAndReplace(frame_tree_node, frame_navigation_entry);

  // Copy most state over, unless cleared in ResetForCommit.
  // Don't copy unique_id_, otherwise it won't be unique.
  copy->bindings_ = bindings_;
  copy->page_type_ = page_type_;
  copy->virtual_url_ = virtual_url_;
  copy->update_virtual_url_with_url_ = update_virtual_url_with_url_;
  copy->title_ = title_;
  copy->favicon_ = favicon_;
  copy->page_id_ = page_id_;
  copy->ssl_ = ssl_;
  copy->transition_type_ = transition_type_;
  copy->user_typed_url_ = user_typed_url_;
  copy->has_post_data_ = has_post_data_;
  copy->post_id_ = post_id_;
  copy->restore_type_ = restore_type_;
  copy->original_request_url_ = original_request_url_;
  copy->is_overriding_user_agent_ = is_overriding_user_agent_;
  copy->timestamp_ = timestamp_;
  copy->http_status_code_ = http_status_code_;
  // ResetForCommit: browser_initiated_post_data_
  copy->screenshot_ = screenshot_;
  copy->extra_headers_ = extra_headers_;
  // ResetForCommit: source_site_instance_
  copy->base_url_for_data_url_ = base_url_for_data_url_;
  // ResetForCommit: is_renderer_initiated_
  copy->cached_display_title_ = cached_display_title_;
  // ResetForCommit: transferred_global_request_id_
  // ResetForCommit: should_replace_entry_
  copy->redirect_chain_ = redirect_chain_;
  // ResetForCommit: should_clear_history_list_
  // ResetForCommit: frame_tree_node_id_
  // ResetForCommit: intent_received_timestamp_
  copy->extra_data_ = extra_data_;

  return copy;
}

CommonNavigationParams NavigationEntryImpl::ConstructCommonNavigationParams(
    FrameMsg_Navigate_Type::Value navigation_type) const {
  FrameMsg_UILoadMetricsReportType::Value report_type =
      FrameMsg_UILoadMetricsReportType::NO_REPORT;
  base::TimeTicks ui_timestamp = base::TimeTicks();
#if defined(OS_ANDROID)
  if (!intent_received_timestamp().is_null())
    report_type = FrameMsg_UILoadMetricsReportType::REPORT_INTENT;
  ui_timestamp = intent_received_timestamp();
#endif

  return CommonNavigationParams(
      GetURL(), GetReferrer(), GetTransitionType(), navigation_type,
      !IsViewSourceMode(), ui_timestamp, report_type, GetBaseURLForDataURL(),
      GetHistoryURLForDataURL());
}

StartNavigationParams NavigationEntryImpl::ConstructStartNavigationParams()
    const {
  std::vector<unsigned char> browser_initiated_post_data;
  if (GetBrowserInitiatedPostData()) {
    browser_initiated_post_data.assign(
        GetBrowserInitiatedPostData()->front(),
        GetBrowserInitiatedPostData()->front() +
            GetBrowserInitiatedPostData()->size());
  }

  return StartNavigationParams(
      GetHasPostData(), extra_headers(), browser_initiated_post_data,
      should_replace_entry(), transferred_global_request_id().child_id,
      transferred_global_request_id().request_id);
}

RequestNavigationParams NavigationEntryImpl::ConstructRequestNavigationParams(
    base::TimeTicks navigation_start,
    bool has_committed_real_load,
    bool intended_as_new_entry,
    int pending_history_list_offset,
    int current_history_list_offset,
    int current_history_list_length) const {
  // Set the redirect chain to the navigation's redirects, unless returning to a
  // completed navigation (whose previous redirects don't apply).
  std::vector<GURL> redirects;
  if (ui::PageTransitionIsNewNavigation(GetTransitionType())) {
    redirects = GetRedirectChain();
  }

  int pending_offset_to_send = pending_history_list_offset;
  int current_offset_to_send = current_history_list_offset;
  int current_length_to_send = current_history_list_length;
  if (should_clear_history_list()) {
    // Set the history list related parameters to the same values a
    // NavigationController would return before its first navigation. This will
    // fully clear the RenderView's view of the session history.
    pending_offset_to_send = -1;
    current_offset_to_send = -1;
    current_length_to_send = 0;
  }
  return RequestNavigationParams(
      GetIsOverridingUserAgent(), navigation_start, redirects,
      GetCanLoadLocalResources(), base::Time::Now(), GetPageState(),
      GetPageID(), GetUniqueID(), has_committed_real_load,
      intended_as_new_entry, pending_offset_to_send, current_offset_to_send,
      current_length_to_send, should_clear_history_list());
}

void NavigationEntryImpl::ResetForCommit() {
  // Any state that only matters when a navigation entry is pending should be
  // cleared here.
  // TODO(creis): This state should be moved to NavigationRequest once
  // PlzNavigate is enabled.
  SetBrowserInitiatedPostData(nullptr);
  set_source_site_instance(nullptr);
  set_is_renderer_initiated(false);
  set_transferred_global_request_id(GlobalRequestID());
  set_should_replace_entry(false);

  set_should_clear_history_list(false);
  set_frame_tree_node_id(-1);

#if defined(OS_ANDROID)
  // Reset the time stamp so that the metrics are not reported if this entry is
  // loaded again in the future.
  set_intent_received_timestamp(base::TimeTicks());
#endif
}

void NavigationEntryImpl::AddOrUpdateFrameEntry(FrameTreeNode* frame_tree_node,
                                                SiteInstanceImpl* site_instance,
                                                const GURL& url,
                                                const Referrer& referrer,
                                                const PageState& page_state) {
  // We should already have a TreeNode for the parent node by the time this node
  // commits.  Find it first.
  DCHECK(frame_tree_node->parent());
  NavigationEntryImpl::TreeNode* parent_node =
      FindFrameEntry(frame_tree_node->parent());
  if (!parent_node) {
    // The renderer should not send a commit for a subframe before its parent.
    // However, we may see commits of subframes when their parent or ancestor is
    // still the initial about:blank page, and we don't currently keep a
    // FrameNavigationEntry for that.  We ignore such commits, similar to how we
    // handle them at the top level.
    // TODO(creis): Consider creating FNEs for initial about:blank commits.
    return;
  }

  // Now check whether we have a TreeNode for the node itself.
  int frame_tree_node_id = frame_tree_node->frame_tree_node_id();
  for (TreeNode* child : parent_node->children) {
    if (child->frame_entry->frame_tree_node_id() == frame_tree_node_id) {
      // Update the existing FrameNavigationEntry (e.g., for replaceState).
      child->frame_entry->UpdateEntry(site_instance, url, referrer, page_state);
      return;
    }
  }

  // No entry exists yet, so create a new one unless it's for about:blank.
  // Unordered list, since we expect to look up entries by frame sequence number
  // or unique name.
  if (url == GURL(url::kAboutBlankURL))
    return;
  FrameNavigationEntry* frame_entry = new FrameNavigationEntry(
      frame_tree_node_id, site_instance, url, referrer);
  frame_entry->set_page_state(page_state);
  parent_node->children.push_back(
      new NavigationEntryImpl::TreeNode(frame_entry));
}

bool NavigationEntryImpl::HasFrameEntry(FrameTreeNode* frame_tree_node) const {
  return FindFrameEntry(frame_tree_node) != nullptr;
}

void NavigationEntryImpl::SetScreenshotPNGData(
    scoped_refptr<base::RefCountedBytes> png_data) {
  screenshot_ = png_data;
  if (screenshot_.get())
    UMA_HISTOGRAM_MEMORY_KB("Overscroll.ScreenshotSize", screenshot_->size());
}

GURL NavigationEntryImpl::GetHistoryURLForDataURL() const {
  return GetBaseURLForDataURL().is_empty() ? GURL() : GetVirtualURL();
}

NavigationEntryImpl::TreeNode* NavigationEntryImpl::FindFrameEntry(
    FrameTreeNode* frame_tree_node) const {
  NavigationEntryImpl::TreeNode* node = nullptr;
  std::queue<NavigationEntryImpl::TreeNode*> work_queue;
  work_queue.push(root_node());
  while (!work_queue.empty()) {
    node = work_queue.front();
    work_queue.pop();
    if (node->MatchesFrame(frame_tree_node)) {
      // Only the root TreeNode should have a FTN ID of -1.
      DCHECK_IMPLIES(node->frame_entry->frame_tree_node_id() == -1,
                     node == root_node());
      return node;
    }
    // Enqueue any children and keep looking.
    for (auto& child : node->children)
      work_queue.push(child);
  }
  return nullptr;
}

}  // namespace content
