// 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 "components/blocked_content/popup_blocker_tab_helper.h"

#include <iterator>
#include <string>

#include "base/metrics/histogram_macros.h"
#include "build/build_config.h"
#include "components/back_forward_cache/back_forward_cache_disable.h"
#include "components/blocked_content/list_item_position.h"
#include "components/blocked_content/popup_navigation_delegate.h"
#include "components/blocked_content/popup_tracker.h"
#include "components/blocked_content/safe_browsing_triggered_popup_blocker.h"
#include "components/content_settings/browser/page_specific_content_settings.h"
#include "content/public/browser/back_forward_cache.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/page_navigator.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "third_party/blink/public/mojom/window_features/window_features.mojom.h"

namespace blocked_content {
const size_t kMaximumNumberOfPopups = 25;

struct PopupBlockerTabHelper::BlockedRequest {
  BlockedRequest(std::unique_ptr<PopupNavigationDelegate> delegate,
                 const blink::mojom::WindowFeatures& window_features,
                 PopupBlockType block_type)
      : delegate(std::move(delegate)),
        window_features(window_features),
        block_type(block_type) {}

  std::unique_ptr<PopupNavigationDelegate> delegate;
  blink::mojom::WindowFeatures window_features;
  PopupBlockType block_type;
};

PopupBlockerTabHelper::PopupBlockerTabHelper(content::WebContents* web_contents)
    : content::WebContentsObserver(web_contents) {
  blocked_content::SafeBrowsingTriggeredPopupBlocker::MaybeCreate(web_contents);
}

PopupBlockerTabHelper::~PopupBlockerTabHelper() = default;

void PopupBlockerTabHelper::DidFinishNavigation(
    content::NavigationHandle* navigation_handle) {
  // Clear all page actions, blocked content notifications and browser actions
  // for this tab, unless this is an same-document navigation. Also only
  // consider main frame navigations that successfully committed.
  if (!navigation_handle->IsInMainFrame() ||
      !navigation_handle->HasCommitted() ||
      navigation_handle->IsSameDocument()) {
    return;
  }

  // Close blocked popups.
  if (!blocked_popups_.empty()) {
    blocked_popups_.clear();
    HidePopupNotification();

    // With back-forward cache we can restore the page, but |blocked_popups_|
    // are lost here and can't be restored at the moment.
    // Disable bfcache here to avoid potential loss of the page state.
    content::BackForwardCache::DisableForRenderFrameHost(
        navigation_handle->GetPreviousRenderFrameHostId(),
        back_forward_cache::DisabledReason(
            back_forward_cache::DisabledReasonId::kPopupBlockerTabHelper));
  }
}

void PopupBlockerTabHelper::HidePopupNotification() {
  auto* pscs = content_settings::PageSpecificContentSettings::GetForFrame(
      web_contents()->GetMainFrame());
  if (pscs)
    pscs->ClearPopupsBlocked();
}

void PopupBlockerTabHelper::AddBlockedPopup(
    std::unique_ptr<PopupNavigationDelegate> delegate,
    const blink::mojom::WindowFeatures& window_features,
    PopupBlockType block_type) {
  LogAction(Action::kBlocked);
  if (blocked_popups_.size() >= kMaximumNumberOfPopups)
    return;

  int id = next_id_;
  next_id_++;
  blocked_popups_[id] = std::make_unique<BlockedRequest>(
      std::move(delegate), window_features, block_type);

  auto* content_settings =
      content_settings::PageSpecificContentSettings::GetForFrame(
          web_contents()->GetMainFrame());
  if (content_settings) {
    content_settings->OnContentBlocked(ContentSettingsType::POPUPS);
  }
  auto* raw_delegate = blocked_popups_[id]->delegate.get();

  manager_.NotifyObservers(id, raw_delegate->GetURL());

  raw_delegate->OnPopupBlocked(web_contents(), GetBlockedPopupsCount());
}

void PopupBlockerTabHelper::ShowBlockedPopup(
    int32_t id,
    WindowOpenDisposition disposition) {
  auto it = blocked_popups_.find(id);
  if (it == blocked_popups_.end())
    return;

  blocked_content::ListItemPosition position =
      blocked_content::GetListItemPositionFromDistance(
          std::distance(blocked_popups_.begin(), it), blocked_popups_.size());

  UMA_HISTOGRAM_ENUMERATION("ContentSettings.Popups.ClickThroughPosition",
                            position);

  BlockedRequest* popup = it->second.get();

  base::Optional<WindowOpenDisposition> updated_disposition;
  if (disposition != WindowOpenDisposition::CURRENT_TAB)
    updated_disposition = disposition;

  PopupNavigationDelegate::NavigateResult result =
      popup->delegate->NavigateWithGesture(popup->window_features,
                                           updated_disposition);
  if (result.navigated_or_inserted_contents) {
    auto* tracker = blocked_content::PopupTracker::CreateForWebContents(
        result.navigated_or_inserted_contents, web_contents(),
        result.disposition);
    tracker->set_is_trusted(true);
  }

  switch (popup->block_type) {
    case PopupBlockType::kNotBlocked:
      NOTREACHED();
      break;
    case PopupBlockType::kNoGesture:
      LogAction(Action::kClickedThroughNoGesture);
      break;
    case PopupBlockType::kAbusive:
      LogAction(Action::kClickedThroughAbusive);
      break;
  }

  blocked_popups_.erase(id);
  if (blocked_popups_.empty())
    HidePopupNotification();
}

void PopupBlockerTabHelper::ShowAllBlockedPopups() {
  PopupIdMap blocked_popups = GetBlockedPopupRequests();
  for (const auto& elem : blocked_popups) {
    ShowBlockedPopup(elem.first, WindowOpenDisposition::CURRENT_TAB);
  }
}

size_t PopupBlockerTabHelper::GetBlockedPopupsCount() const {
  return blocked_popups_.size();
}

PopupBlockerTabHelper::PopupIdMap
PopupBlockerTabHelper::GetBlockedPopupRequests() {
  PopupIdMap result;
  for (const auto& it : blocked_popups_) {
    result[it.first] = it.second->delegate->GetURL();
  }
  return result;
}

// static
void PopupBlockerTabHelper::LogAction(Action action) {
  UMA_HISTOGRAM_ENUMERATION("ContentSettings.Popups.BlockerActions", action);
}

WEB_CONTENTS_USER_DATA_KEY_IMPL(PopupBlockerTabHelper)

}  // namespace blocked_content
