// Copyright (c) 2012 The Chromium Embedded Framework 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 "libcef/browser/browser_info.h"

#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/values_impl.h"

#include "base/logging.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/public/browser/render_process_host.h"
#include "ipc/ipc_message.h"

CefBrowserInfo::FrameInfo::~FrameInfo() {
  if (frame_ && !is_main_frame_) {
    // Disassociate sub-frames from the browser.
    frame_->Detach();
  }
}

CefBrowserInfo::CefBrowserInfo(int browser_id,
                               bool is_popup,
                               bool is_windowless,
                               CefRefPtr<CefDictionaryValue> extra_info)
    : browser_id_(browser_id),
      is_popup_(is_popup),
      is_windowless_(is_windowless),
      extra_info_(extra_info) {
  DCHECK_GT(browser_id, 0);
}

CefBrowserInfo::~CefBrowserInfo() {}

CefRefPtr<CefBrowserHostImpl> CefBrowserInfo::browser() const {
  base::AutoLock lock_scope(lock_);
  return browser_;
}

void CefBrowserInfo::SetBrowser(CefRefPtr<CefBrowserHostImpl> browser) {
  base::AutoLock lock_scope(lock_);
  browser_ = browser;

  if (!browser) {
    RemoveAllFrames();
  }
}

void CefBrowserInfo::MaybeCreateFrame(content::RenderFrameHost* host,
                                      bool is_guest_view) {
  CEF_REQUIRE_UIT();

  const auto frame_id = CefFrameHostImpl::MakeFrameId(host);
  const int frame_tree_node_id = host->GetFrameTreeNodeId();
  const bool is_main_frame = (host->GetParent() == nullptr);

  // A speculative RFH will be created in response to a browser-initiated
  // cross-origin navigation (e.g. via LoadURL) and eventually either discarded
  // or swapped in based on whether the navigation is committed. We'll create a
  // frame object for the speculative RFH so that it can be found by
  // frame/routing ID. However, we won't replace the main frame with a
  // speculative RFH until after it's swapped in, and we'll generally prefer to
  // return a non-speculative RFH for the same node ID if one exists.
  const bool is_speculative = (static_cast<content::RenderFrameHostImpl*>(host)
                                   ->frame_tree_node()
                                   ->render_manager()
                                   ->current_frame_host() != host);

  base::AutoLock lock_scope(lock_);
  DCHECK(browser_);

  const auto it = frame_id_map_.find(frame_id);
  if (it != frame_id_map_.end()) {
    auto info = it->second;

#if DCHECK_IS_ON()
    // Check that the frame info hasn't changed unexpectedly.
    DCHECK_EQ(info->frame_id_, frame_id);
    DCHECK_EQ(info->frame_tree_node_id_, frame_tree_node_id);
    DCHECK_EQ(info->is_guest_view_, is_guest_view);
    DCHECK_EQ(info->is_main_frame_, is_main_frame);
#endif

    if (!info->is_guest_view_ && info->is_speculative_ && !is_speculative) {
      // Upgrade the frame info from speculative to non-speculative.
      if (info->is_main_frame_) {
        if (main_frame_) {
          // Update the existing main frame object.
          main_frame_->SetRenderFrameHost(host);
          info->frame_ = main_frame_;
        } else {
          // Set the main frame object.
          main_frame_ = info->frame_;
        }
      }
      info->is_speculative_ = false;
      MaybeUpdateFrameTreeNodeIdMap(info);
    }
    return;
  }

  auto frame_info = new FrameInfo;
  frame_info->host_ = host;
  frame_info->frame_id_ = frame_id;
  frame_info->frame_tree_node_id_ = frame_tree_node_id;
  frame_info->is_guest_view_ = is_guest_view;
  frame_info->is_main_frame_ = is_main_frame;
  frame_info->is_speculative_ = is_speculative;

  // Guest views don't get their own CefBrowser or CefFrame objects.
  if (!is_guest_view) {
    if (is_main_frame && main_frame_ && !is_speculative) {
      // Update the existing main frame object.
      main_frame_->SetRenderFrameHost(host);
      frame_info->frame_ = main_frame_;
    } else {
      // Create a new frame object.
      frame_info->frame_ = new CefFrameHostImpl(this, host);
      if (is_main_frame && !is_speculative) {
        main_frame_ = frame_info->frame_;
      }
    }
#if DCHECK_IS_ON()
    // Check that the frame info hasn't changed unexpectedly.
    DCHECK_EQ(frame_id, frame_info->frame_->GetIdentifier());
    DCHECK_EQ(frame_info->is_main_frame_, frame_info->frame_->IsMain());
#endif
  }

  browser_->request_context()->OnRenderFrameCreated(
      host->GetProcess()->GetID(), host->GetRoutingID(), frame_tree_node_id,
      is_main_frame, is_guest_view);

  // Populate the lookup maps.
  frame_id_map_.insert(std::make_pair(frame_id, frame_info));
  MaybeUpdateFrameTreeNodeIdMap(frame_info);

  // And finally set the ownership.
  frame_info_set_.insert(base::WrapUnique(frame_info));
}

void CefBrowserInfo::RemoveFrame(content::RenderFrameHost* host) {
  CEF_REQUIRE_UIT();

  base::AutoLock lock_scope(lock_);

  const auto frame_id = CefFrameHostImpl::MakeFrameId(host);

  auto it = frame_id_map_.find(frame_id);
  DCHECK(it != frame_id_map_.end());

  auto frame_info = it->second;

  browser_->request_context()->OnRenderFrameDeleted(
      host->GetProcess()->GetID(), host->GetRoutingID(),
      frame_info->frame_tree_node_id_, frame_info->is_main_frame_,
      frame_info->is_guest_view_);

  // Remove from the lookup maps.
  frame_id_map_.erase(it);

  // A new RFH with the same node ID may be added before the old RFH is deleted,
  // or this might be a speculative RFH. Therefore only delete the map entry if
  // it's currently pointing to the to-be-deleted frame info object.
  {
    auto it2 = frame_tree_node_id_map_.find(frame_info->frame_tree_node_id_);
    if (it2 != frame_tree_node_id_map_.end() && it2->second == frame_info) {
      frame_tree_node_id_map_.erase(frame_info->frame_tree_node_id_);
    }
  }

  // And finally delete the frame info.
  {
    auto it2 = frame_info_set_.find(frame_info);
    frame_info_set_.erase(it2);
  }
}

CefRefPtr<CefFrameHostImpl> CefBrowserInfo::GetMainFrame() {
  base::AutoLock lock_scope(lock_);
  DCHECK(browser_);
  if (!main_frame_) {
    // Create a temporary object that will eventually be updated with real
    // routing information.
    main_frame_ =
        new CefFrameHostImpl(this, true, CefFrameHostImpl::kInvalidFrameId);
  }
  return main_frame_;
}

CefRefPtr<CefFrameHostImpl> CefBrowserInfo::CreateTempSubFrame(
    int64_t parent_frame_id) {
  CefRefPtr<CefFrameHostImpl> parent = GetFrameForId(parent_frame_id);
  if (!parent)
    parent = GetMainFrame();
  return new CefFrameHostImpl(this, false, parent->GetIdentifier());
}

CefRefPtr<CefFrameHostImpl> CefBrowserInfo::GetFrameForHost(
    const content::RenderFrameHost* host,
    bool* is_guest_view) const {
  if (is_guest_view)
    *is_guest_view = false;

  if (!host)
    return nullptr;

  return GetFrameForId(CefFrameHostImpl::MakeFrameId(host), is_guest_view);
}

CefRefPtr<CefFrameHostImpl> CefBrowserInfo::GetFrameForRoute(
    int32_t render_process_id,
    int32_t render_routing_id,
    bool* is_guest_view) const {
  if (is_guest_view)
    *is_guest_view = false;

  if (render_process_id < 0 || render_routing_id < 0)
    return nullptr;

  return GetFrameForId(
      CefFrameHostImpl::MakeFrameId(render_process_id, render_routing_id),
      is_guest_view);
}

CefRefPtr<CefFrameHostImpl> CefBrowserInfo::GetFrameForId(
    int64_t frame_id,
    bool* is_guest_view) const {
  if (is_guest_view)
    *is_guest_view = false;

  if (frame_id < 0)
    return nullptr;

  base::AutoLock lock_scope(lock_);

  const auto it = frame_id_map_.find(frame_id);
  if (it != frame_id_map_.end()) {
    const auto info = it->second;

    if (info->is_guest_view_) {
      if (is_guest_view)
        *is_guest_view = true;
      return nullptr;
    }

    if (info->is_speculative_) {
      if (info->is_main_frame_ && main_frame_) {
        // Always prefer the non-speculative main frame.
        return main_frame_;
      } else {
        // Always prefer an existing non-speculative frame for the same node ID.
        bool is_guest_view_tmp;
        auto frame = GetFrameForFrameTreeNodeInternal(info->frame_tree_node_id_,
                                                      &is_guest_view_tmp);
        if (is_guest_view_tmp) {
          if (is_guest_view)
            *is_guest_view = true;
          return nullptr;
        }
        if (frame)
          return frame;
      }

      LOG(WARNING) << "Returning a speculative frame for frame id " << frame_id;
    }

    DCHECK(info->frame_);
    return info->frame_;
  }

  return nullptr;
}

CefRefPtr<CefFrameHostImpl> CefBrowserInfo::GetFrameForFrameTreeNode(
    int frame_tree_node_id,
    bool* is_guest_view) const {
  if (is_guest_view)
    *is_guest_view = false;

  if (frame_tree_node_id < 0)
    return nullptr;

  base::AutoLock lock_scope(lock_);
  return GetFrameForFrameTreeNodeInternal(frame_tree_node_id, is_guest_view);
}

CefBrowserInfo::FrameHostList CefBrowserInfo::GetAllFrames() const {
  base::AutoLock lock_scope(lock_);
  FrameHostList frames;
  for (const auto& info : frame_info_set_) {
    if (info->frame_ && !info->is_speculative_)
      frames.insert(info->frame_);
  }
  return frames;
}

void CefBrowserInfo::MaybeUpdateFrameTreeNodeIdMap(FrameInfo* info) {
  lock_.AssertAcquired();

  auto it = frame_tree_node_id_map_.find(info->frame_tree_node_id_);
  const bool has_entry = (it != frame_tree_node_id_map_.end());

  if (has_entry && it->second == info) {
    // Already mapping to |info|.
    return;
  }

  // Don't replace an existing node ID entry with a speculative RFH, but do
  // add an entry if one doesn't already exist.
  if (!info->is_speculative_ || !has_entry) {
    // A new RFH with the same node ID may be added before the old RFH is
    // deleted. To avoid duplicate entries in the map remove the old entry, if
    // any, before adding the new entry.
    if (has_entry)
      frame_tree_node_id_map_.erase(it);

    frame_tree_node_id_map_.insert(
        std::make_pair(info->frame_tree_node_id_, info));
  }
}

CefRefPtr<CefFrameHostImpl> CefBrowserInfo::GetFrameForFrameTreeNodeInternal(
    int frame_tree_node_id,
    bool* is_guest_view) const {
  if (is_guest_view)
    *is_guest_view = false;

  lock_.AssertAcquired();

  const auto it = frame_tree_node_id_map_.find(frame_tree_node_id);
  if (it != frame_tree_node_id_map_.end()) {
    const auto info = it->second;

    LOG_IF(WARNING, info->is_speculative_)
        << "Returning a speculative frame for node id " << frame_tree_node_id;

    if (info->is_guest_view_) {
      if (is_guest_view)
        *is_guest_view = true;
      return nullptr;
    }

    DCHECK(info->frame_);
    return info->frame_;
  }

  return nullptr;
}

void CefBrowserInfo::RemoveAllFrames() {
  lock_.AssertAcquired();

  // Clear the lookup maps.
  frame_id_map_.clear();
  frame_tree_node_id_map_.clear();

  // Explicitly Detach main frames.
  for (auto& info : frame_info_set_) {
    if (info->frame_ && info->is_main_frame_)
      info->frame_->Detach();
  }

  if (main_frame_) {
    main_frame_->Detach();
    main_frame_ = nullptr;
  }

  // And finally delete the frame info.
  frame_info_set_.clear();
}
