// Copyright 2015 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_manager.h"

#include <utility>

#include "libcef/browser/browser_host_impl.h"
#include "libcef/browser/browser_platform_delegate.h"
#include "libcef/browser/extensions/browser_extensions_util.h"
#include "libcef/browser/thread_util.h"
#include "libcef/common/cef_messages.h"
#include "libcef/common/cef_switches.h"
#include "libcef/common/extensions/extensions_util.h"
#include "libcef/common/values_impl.h"

#include "base/command_line.h"
#include "base/logging.h"
#include "content/common/view_messages.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/child_process_host.h"

namespace {

// Timeout delay for new browser info responses.
const int64_t kNewBrowserInfoResponseTimeoutMs = 2000;

void TranslatePopupFeatures(const blink::mojom::WindowFeatures& webKitFeatures,
                            CefPopupFeatures& features) {
  features.x = static_cast<int>(webKitFeatures.x);
  features.xSet = webKitFeatures.has_x;
  features.y = static_cast<int>(webKitFeatures.y);
  features.ySet = webKitFeatures.has_y;
  features.width = static_cast<int>(webKitFeatures.width);
  features.widthSet = webKitFeatures.has_width;
  features.height = static_cast<int>(webKitFeatures.height);
  features.heightSet = webKitFeatures.has_height;

  features.menuBarVisible = webKitFeatures.menu_bar_visible;
  features.statusBarVisible = webKitFeatures.status_bar_visible;
  features.toolBarVisible = webKitFeatures.tool_bar_visible;
  features.scrollbarsVisible = webKitFeatures.scrollbars_visible;
}

CefBrowserInfoManager* g_info_manager = nullptr;

}  // namespace

CefBrowserInfoManager::CefBrowserInfoManager() {
  DCHECK(!g_info_manager);
  g_info_manager = this;
}

CefBrowserInfoManager::~CefBrowserInfoManager() {
  DCHECK(browser_info_list_.empty());
  g_info_manager = nullptr;
}

// static
CefBrowserInfoManager* CefBrowserInfoManager::GetInstance() {
  return g_info_manager;
}

scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::CreateBrowserInfo(
    bool is_popup,
    bool is_windowless,
    CefRefPtr<CefDictionaryValue> extra_info) {
  base::AutoLock lock_scope(browser_info_lock_);

  scoped_refptr<CefBrowserInfo> browser_info = new CefBrowserInfo(
      ++next_browser_id_, is_popup, is_windowless, extra_info);
  browser_info_list_.push_back(browser_info);

  return browser_info;
}

scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::CreatePopupBrowserInfo(
    content::WebContents* new_contents,
    bool is_windowless,
    CefRefPtr<CefDictionaryValue> extra_info) {
  base::AutoLock lock_scope(browser_info_lock_);

  auto frame_host = new_contents->GetMainFrame();
  const int render_process_id = frame_host->GetProcess()->GetID();
  const auto frame_id = CefFrameHostImpl::MakeFrameId(frame_host);

  scoped_refptr<CefBrowserInfo> browser_info =
      new CefBrowserInfo(++next_browser_id_, true, is_windowless, extra_info);
  browser_info_list_.push_back(browser_info);

  // Continue any pending NewBrowserInfo request.
  auto it = pending_new_browser_info_map_.find(frame_id);
  if (it != pending_new_browser_info_map_.end()) {
    SendNewBrowserInfoResponse(render_process_id, browser_info,
                               false /* is_guest_view */,
                               it->second->reply_msg);
    pending_new_browser_info_map_.erase(it);
  }

  return browser_info;
}

bool CefBrowserInfoManager::CanCreateWindow(
    content::RenderFrameHost* opener,
    const GURL& target_url,
    const content::Referrer& referrer,
    const std::string& frame_name,
    WindowOpenDisposition disposition,
    const blink::mojom::WindowFeatures& features,
    bool user_gesture,
    bool opener_suppressed,
    bool* no_javascript_access) {
  CEF_REQUIRE_UIT();

  bool is_guest_view = false;
  CefRefPtr<CefBrowserHostImpl> browser =
      extensions::GetOwnerBrowserForHost(opener, &is_guest_view);
  DCHECK(browser.get());
  if (!browser.get()) {
    // Cancel the popup.
    return false;
  }

  if (is_guest_view) {
    content::OpenURLParams params(target_url, referrer, disposition,
                                  ui::PAGE_TRANSITION_LINK, true);
    params.user_gesture = user_gesture;

    // Pass navigation to the owner browser.
    CEF_POST_TASK(
        CEF_UIT,
        base::Bind(base::IgnoreResult(&CefBrowserHostImpl::OpenURLFromTab),
                   browser.get(), nullptr, params));

    // Cancel the popup.
    return false;
  }

  CefRefPtr<CefClient> client = browser->GetClient();
  bool allow = true;

  std::unique_ptr<CefWindowInfo> window_info(new CefWindowInfo);

#if defined(OS_WIN)
  window_info->SetAsPopup(nullptr, CefString());
#endif

  auto pending_popup = std::make_unique<CefBrowserInfoManager::PendingPopup>();
  pending_popup->step = CefBrowserInfoManager::PendingPopup::CAN_CREATE_WINDOW;
  pending_popup->opener_render_process_id = opener->GetProcess()->GetID();
  pending_popup->opener_render_routing_id = opener->GetRoutingID();
  pending_popup->target_url = target_url;
  pending_popup->target_frame_name = frame_name;

  // Start with the current browser's settings.
  pending_popup->client = client;
  pending_popup->settings = browser->settings();

  if (client.get()) {
    CefRefPtr<CefLifeSpanHandler> handler = client->GetLifeSpanHandler();
    if (handler.get()) {
      CefRefPtr<CefFrame> opener_frame = browser->GetFrameForHost(opener);
      DCHECK(opener_frame);

      CefPopupFeatures cef_features;
      TranslatePopupFeatures(features, cef_features);

#if (defined(OS_WIN) || defined(OS_MACOSX))
      // Default to the size from the popup features.
      if (cef_features.xSet)
        window_info->x = cef_features.x;
      if (cef_features.ySet)
        window_info->y = cef_features.y;
      if (cef_features.widthSet)
        window_info->width = cef_features.width;
      if (cef_features.heightSet)
        window_info->height = cef_features.height;
#endif

      allow = !handler->OnBeforePopup(
          browser.get(), opener_frame, pending_popup->target_url.spec(),
          pending_popup->target_frame_name,
          static_cast<cef_window_open_disposition_t>(disposition), user_gesture,
          cef_features, *window_info, pending_popup->client,
          pending_popup->settings, pending_popup->extra_info,
          no_javascript_access);
    }
  }

  if (allow) {
    CefBrowserHostImpl::CreateParams create_params;

    if (!browser->IsViewsHosted())
      create_params.window_info = std::move(window_info);

    create_params.settings = pending_popup->settings;
    create_params.client = pending_popup->client;
    create_params.extra_info = pending_popup->extra_info;

    pending_popup->platform_delegate =
        CefBrowserPlatformDelegate::Create(create_params);
    CHECK(pending_popup->platform_delegate.get());

    // Between the calls to CanCreateWindow and GetCustomWebContentsView
    // RenderViewHostImpl::CreateNewWindow() will call
    // RenderProcessHostImpl::FilterURL() which, in the case of "javascript:"
    // URIs, rewrites the URL to "about:blank". We need to apply the same filter
    // otherwise GetCustomWebContentsView will fail to retrieve the PopupInfo.
    opener->GetProcess()->FilterURL(false, &pending_popup->target_url);

    PushPendingPopup(std::move(pending_popup));
  }

  return allow;
}

void CefBrowserInfoManager::GetCustomWebContentsView(
    const GURL& target_url,
    int opener_render_process_id,
    int opener_render_routing_id,
    content::WebContentsView** view,
    content::RenderViewHostDelegateView** delegate_view) {
  CEF_REQUIRE_UIT();

  std::unique_ptr<CefBrowserInfoManager::PendingPopup> pending_popup =
      PopPendingPopup(CefBrowserInfoManager::PendingPopup::CAN_CREATE_WINDOW,
                      opener_render_process_id, opener_render_routing_id,
                      target_url);
  DCHECK(pending_popup.get());
  DCHECK(pending_popup->platform_delegate.get());

  if (pending_popup->platform_delegate->IsWindowless()) {
    pending_popup->platform_delegate->CreateViewForWebContents(view,
                                                               delegate_view);
  }

  pending_popup->step =
      CefBrowserInfoManager::PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW;
  PushPendingPopup(std::move(pending_popup));
}

void CefBrowserInfoManager::WebContentsCreated(
    const GURL& target_url,
    int opener_render_process_id,
    int opener_render_routing_id,
    CefBrowserSettings& settings,
    CefRefPtr<CefClient>& client,
    std::unique_ptr<CefBrowserPlatformDelegate>& platform_delegate,
    CefRefPtr<CefDictionaryValue>& extra_info) {
  CEF_REQUIRE_UIT();

  std::unique_ptr<CefBrowserInfoManager::PendingPopup> pending_popup =
      PopPendingPopup(
          CefBrowserInfoManager::PendingPopup::GET_CUSTOM_WEB_CONTENTS_VIEW,
          opener_render_process_id, opener_render_routing_id, target_url);
  DCHECK(pending_popup.get());
  DCHECK(pending_popup->platform_delegate.get());

  settings = pending_popup->settings;
  client = pending_popup->client;
  platform_delegate = std::move(pending_popup->platform_delegate);
  extra_info = pending_popup->extra_info;
}

void CefBrowserInfoManager::OnGetNewBrowserInfo(int render_process_id,
                                                int render_routing_id,
                                                IPC::Message* reply_msg) {
  DCHECK_NE(render_process_id, content::ChildProcessHost::kInvalidUniqueID);
  DCHECK_GT(render_routing_id, 0);
  DCHECK(reply_msg);

  base::AutoLock lock_scope(browser_info_lock_);

  bool is_guest_view = false;

  scoped_refptr<CefBrowserInfo> browser_info =
      GetBrowserInfo(render_process_id, render_routing_id, &is_guest_view);

  if (browser_info.get()) {
    // Send the response immediately.
    SendNewBrowserInfoResponse(render_process_id, browser_info, is_guest_view,
                               reply_msg);
    return;
  }

  const auto frame_id =
      CefFrameHostImpl::MakeFrameId(render_process_id, render_routing_id);

  // Verify that no request for the same route is currently queued.
  DCHECK(pending_new_browser_info_map_.find(frame_id) ==
         pending_new_browser_info_map_.end());

  const int timeout_id = ++next_timeout_id_;

  // Queue the request.
  std::unique_ptr<PendingNewBrowserInfo> pending(new PendingNewBrowserInfo());
  pending->render_process_id = render_process_id;
  pending->render_routing_id = render_routing_id;
  pending->timeout_id = timeout_id;
  pending->reply_msg = reply_msg;
  pending_new_browser_info_map_.insert(
      std::make_pair(frame_id, std::move(pending)));

  // Register a timeout for the pending response so that the renderer process
  // doesn't hang forever.
  if (!base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableNewBrowserInfoTimeout)) {
    CEF_POST_DELAYED_TASK(
        CEF_UIT,
        base::BindOnce(&CefBrowserInfoManager::TimeoutNewBrowserInfoResponse,
                       frame_id, timeout_id),
        kNewBrowserInfoResponseTimeoutMs);
  }
}

void CefBrowserInfoManager::RemoveBrowserInfo(
    scoped_refptr<CefBrowserInfo> browser_info) {
  base::AutoLock lock_scope(browser_info_lock_);

  BrowserInfoList::iterator it = browser_info_list_.begin();
  for (; it != browser_info_list_.end(); ++it) {
    if (*it == browser_info) {
      browser_info_list_.erase(it);
      return;
    }
  }

  NOTREACHED();
}

void CefBrowserInfoManager::DestroyAllBrowsers() {
  BrowserInfoList list;

  {
    base::AutoLock lock_scope(browser_info_lock_);
    list = browser_info_list_;
  }

  // Destroy any remaining browser windows.
  if (!list.empty()) {
    BrowserInfoList::iterator it = list.begin();
    for (; it != list.end(); ++it) {
      CefRefPtr<CefBrowserHostImpl> browser = (*it)->browser();
      DCHECK(browser.get());
      if (browser.get()) {
        // DestroyBrowser will call RemoveBrowserInfo.
        browser->DestroyBrowser();
      }
    }
  }

#if DCHECK_IS_ON()
  {
    // Verify that all browser windows have been destroyed.
    base::AutoLock lock_scope(browser_info_lock_);
    DCHECK(browser_info_list_.empty());
  }
#endif
}

scoped_refptr<CefBrowserInfo>
CefBrowserInfoManager::GetBrowserInfoForFrameRoute(int render_process_id,
                                                   int render_routing_id,
                                                   bool* is_guest_view) {
  base::AutoLock lock_scope(browser_info_lock_);
  return GetBrowserInfo(render_process_id, render_routing_id, is_guest_view);
}

scoped_refptr<CefBrowserInfo>
CefBrowserInfoManager::GetBrowserInfoForFrameTreeNode(int frame_tree_node_id,
                                                      bool* is_guest_view) {
  if (is_guest_view)
    *is_guest_view = false;

  if (frame_tree_node_id < 0)
    return nullptr;

  base::AutoLock lock_scope(browser_info_lock_);

  for (const auto& browser_info : browser_info_list_) {
    bool is_guest_view_tmp;
    auto frame = browser_info->GetFrameForFrameTreeNode(frame_tree_node_id,
                                                        &is_guest_view_tmp);
    if (frame || is_guest_view_tmp) {
      if (is_guest_view)
        *is_guest_view = is_guest_view_tmp;
      return browser_info;
    }
  }

  return nullptr;
}

CefBrowserInfoManager::BrowserInfoList
CefBrowserInfoManager::GetBrowserInfoList() {
  base::AutoLock lock_scope(browser_info_lock_);
  BrowserInfoList copy;
  copy.assign(browser_info_list_.begin(), browser_info_list_.end());
  return copy;
}

void CefBrowserInfoManager::RenderProcessHostDestroyed(
    content::RenderProcessHost* host) {
  CEF_REQUIRE_UIT();

  const int render_process_id = host->GetID();
  DCHECK_GT(render_process_id, 0);

  // Remove all pending requests that reference the destroyed host.
  {
    base::AutoLock lock_scope(browser_info_lock_);

    PendingNewBrowserInfoMap::iterator it =
        pending_new_browser_info_map_.begin();
    while (it != pending_new_browser_info_map_.end()) {
      auto info = it->second.get();
      if (info->render_process_id == render_process_id)
        it = pending_new_browser_info_map_.erase(it);
      else
        ++it;
    }
  }

  // Remove all pending popups that reference the destroyed host as the opener.
  {
    PendingPopupList::iterator it = pending_popup_list_.begin();
    while (it != pending_popup_list_.end()) {
      PendingPopup* popup = it->get();
      if (popup->opener_render_process_id == render_process_id) {
        it = pending_popup_list_.erase(it);
      } else {
        ++it;
      }
    }
  }
}

void CefBrowserInfoManager::PushPendingPopup(
    std::unique_ptr<PendingPopup> popup) {
  CEF_REQUIRE_UIT();
  pending_popup_list_.push_back(std::move(popup));
}

std::unique_ptr<CefBrowserInfoManager::PendingPopup>
CefBrowserInfoManager::PopPendingPopup(PendingPopup::Step step,
                                       int opener_render_process_id,
                                       int opener_render_routing_id,
                                       const GURL& target_url) {
  CEF_REQUIRE_UIT();
  DCHECK_GT(opener_render_process_id, 0);
  DCHECK_GT(opener_render_routing_id, 0);

  PendingPopupList::iterator it = pending_popup_list_.begin();
  for (; it != pending_popup_list_.end(); ++it) {
    PendingPopup* popup = it->get();
    if (popup->step == step &&
        popup->opener_render_process_id == opener_render_process_id &&
        popup->opener_render_routing_id == opener_render_routing_id &&
        popup->target_url == target_url) {
      // Transfer ownership of the pointer.
      it->release();
      pending_popup_list_.erase(it);
      return base::WrapUnique(popup);
    }
  }

  return nullptr;
}

scoped_refptr<CefBrowserInfo> CefBrowserInfoManager::GetBrowserInfo(
    int render_process_id,
    int render_routing_id,
    bool* is_guest_view) {
  browser_info_lock_.AssertAcquired();

  if (is_guest_view)
    *is_guest_view = false;

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

  for (const auto& browser_info : browser_info_list_) {
    bool is_guest_view_tmp;
    auto frame = browser_info->GetFrameForRoute(
        render_process_id, render_routing_id, &is_guest_view_tmp);
    if (frame || is_guest_view_tmp) {
      if (is_guest_view)
        *is_guest_view = is_guest_view_tmp;
      return browser_info;
    }
  }

  return nullptr;
}

// static
void CefBrowserInfoManager::SendNewBrowserInfoResponse(
    int render_process_id,
    scoped_refptr<CefBrowserInfo> browser_info,
    bool is_guest_view,
    IPC::Message* reply_msg) {
  if (!CEF_CURRENTLY_ON_UIT()) {
    CEF_POST_TASK(
        CEF_UIT,
        base::Bind(&CefBrowserInfoManager::SendNewBrowserInfoResponse,
                   render_process_id, browser_info, is_guest_view, reply_msg));
    return;
  }

  content::RenderProcessHost* host =
      content::RenderProcessHost::FromID(render_process_id);
  if (!host) {
    delete reply_msg;
    return;
  }

  CefProcessHostMsg_GetNewBrowserInfo_Params params;
  params.is_guest_view = is_guest_view;

  if (browser_info) {
    params.browser_id = browser_info->browser_id();
    params.is_windowless = browser_info->is_windowless();
    params.is_popup = browser_info->is_popup();

    auto extra_info = browser_info->extra_info();
    if (extra_info) {
      auto extra_info_impl =
          static_cast<CefDictionaryValueImpl*>(extra_info.get());
      auto extra_info_value = extra_info_impl->CopyValue();
      extra_info_value->Swap(&params.extra_info);
    }
  } else {
    // The new browser info response has timed out.
    params.browser_id = -1;
  }

  CefProcessHostMsg_GetNewBrowserInfo::WriteReplyParams(reply_msg, params);
  host->Send(reply_msg);
}

// static
void CefBrowserInfoManager::TimeoutNewBrowserInfoResponse(int64_t frame_id,
                                                          int timeout_id) {
  if (!g_info_manager)
    return;

  base::AutoLock lock_scope(g_info_manager->browser_info_lock_);

  // Continue the NewBrowserInfo request if it's still pending.
  auto it = g_info_manager->pending_new_browser_info_map_.find(frame_id);
  if (it != g_info_manager->pending_new_browser_info_map_.end()) {
    const auto& pending_info = it->second;
    // Don't accidentally timeout a new request for the same frame.
    if (pending_info->timeout_id != timeout_id)
      return;

    LOG(ERROR) << "Timeout of new browser info response for frame process id "
               << pending_info->render_process_id << " and routing id "
               << pending_info->render_routing_id;

    SendNewBrowserInfoResponse(pending_info->render_process_id, nullptr,
                               false /* is_guest_view */,
                               pending_info->reply_msg);
    g_info_manager->pending_new_browser_info_map_.erase(it);
  }
}
