// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/ui/views/site_data/page_specific_site_data_dialog_controller.h"

#include "base/logging.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/user_metrics.h"
#include "base/metrics/user_metrics_action.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/infobars/browser_infobar_manager.h"
#include "chrome/browser/infobars/infobar_features.h"
#include "chrome/browser/infobars/infobar_spec.h"
#include "chrome/browser/ui/collected_cookies_infobar_delegate.h"
#include "chrome/browser/ui/views/site_data/page_specific_site_data_dialog.h"
#include "chrome/grit/generated_resources.h"
#include "components/infobars/content/content_infobar_manager.h"
#include "components/tabs/public/tab_interface.h"
#include "components/vector_icons/vector_icons.h"
#include "components/web_modal/web_contents_modal_dialog_manager.h"
#include "content/public/browser/navigation_controller.h"
#include "content/public/browser/web_contents.h"
#include "content/public/browser/web_contents_user_data.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/base/ui_base_features.h"
#include "ui/views/widget/widget.h"

void RecordPageSpecificSiteDataDialogOpenedAction() {
  base::RecordAction(base::UserMetricsAction("CookiesInUseDialog.Opened"));
}

void RecordPageSpecificSiteDataDialogRemoveButtonClickedAction() {
  base::RecordAction(
      base::UserMetricsAction("CookiesInUseDialog.RemoveButtonClicked"));
}

// static
views::View* PageSpecificSiteDataDialogController::GetDialogView(
    content::WebContents* web_contents) {
  PageSpecificSiteDataDialogController* handle =
      static_cast<PageSpecificSiteDataDialogController*>(
          web_contents->GetUserData(
              PageSpecificSiteDataDialogController::UserDataKey()));
  if (!handle) {
    return nullptr;
  }
  return handle->GetDialogView();
}

// static
void PageSpecificSiteDataDialogController::CreateAndShowForWebContents(
    content::WebContents* web_contents) {
  views::View* const instance =
      PageSpecificSiteDataDialogController::GetDialogView(web_contents);
  if (!instance) {
    PageSpecificSiteDataDialogController::CreateForWebContents(web_contents);
    return;
  }

  // On rare occasions, |instance| may have started, but not finished,
  // closing. In this case, the modal dialog manager will have removed the
  // dialog from its list of tracked dialogs, and therefore might not have any
  // active dialog. This should be rare enough that it's not worth trying to
  // re-open the dialog. See https://crbug.com/40638525
  if (instance->GetWidget()->IsClosed()) {
    return;
  }

  auto* dialog_manager =
      web_modal::WebContentsModalDialogManager::FromWebContents(web_contents);
  CHECK(dialog_manager->IsDialogActive());
  dialog_manager->FocusTopmostDialog();
}

PageSpecificSiteDataDialogController::PageSpecificSiteDataDialogController(
    content::WebContents* web_contents)
    : content::WebContentsUserData<PageSpecificSiteDataDialogController>(
          *web_contents) {
  views::Widget* const widget = ShowPageSpecificSiteDataDialog(web_contents);
  tracker_.SetView(widget->GetRootView());
}

PageSpecificSiteDataDialogController::~PageSpecificSiteDataDialogController() =
    default;

views::View* PageSpecificSiteDataDialogController::GetDialogView() {
  // TODO(crbug.com/40231917): Revisit this after the new dialog is launched.
  // Consider not using the view tracker here but using instead a flag to
  // track if the widget is open and a CancelableCallback to track that the
  // widget is closed.
  return tracker_.view();
}

// static
void PageSpecificSiteDataDialogController::ShowCollectedCookiesInfoBar(
    content::WebContents* web_contents) {
  auto* browser_infobar_manager =
      infobars::BrowserInfoBarManager::From(g_browser_process);
  CHECK(browser_infobar_manager);
  auto* tab = tabs::TabInterface::MaybeGetFromContents(web_contents);
  if (tab) {
    browser_infobar_manager->Show(
        tab, infobars::InfoBarDelegate::COLLECTED_COOKIES_INFOBAR_DELEGATE);
  }
}

WEB_CONTENTS_USER_DATA_KEY_IMPL(PageSpecificSiteDataDialogController);
