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

#include "components/javascript_dialogs/tab_modal_dialog_manager.h"

#include <utility>

#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_macros.h"
#include "base/strings/stringprintf.h"
#include "components/javascript_dialogs/app_modal_dialog_manager.h"
#include "components/javascript_dialogs/tab_modal_dialog_view.h"
#include "components/navigation_metrics/navigation_metrics.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/navigation_handle.h"
#include "content/public/browser/render_frame_host.h"
#include "services/metrics/public/cpp/ukm_builders.h"
#include "services/metrics/public/cpp/ukm_recorder.h"
#include "ui/gfx/text_elider.h"
#include "url/origin.h"

namespace javascript_dialogs {

namespace {

AppModalDialogManager* GetAppModalDialogManager() {
  return AppModalDialogManager::GetInstance();
}

}  // namespace

TabModalDialogManager::~TabModalDialogManager() {
  CloseDialog(DismissalCause::kTabHelperDestroyed, false, std::u16string());
}

void TabModalDialogManager::BrowserActiveStateChanged() {
  if (delegate_->IsWebContentsForemost())
    OnVisibilityChanged(content::Visibility::VISIBLE);
  else
    HandleTabSwitchAway(DismissalCause::kBrowserSwitched);
}

void TabModalDialogManager::CloseDialogWithReason(DismissalCause reason) {
  CloseDialog(reason, false, std::u16string());
}

void TabModalDialogManager::SetDialogShownCallbackForTesting(
    base::OnceClosure callback) {
  dialog_shown_ = std::move(callback);
}

bool TabModalDialogManager::IsShowingDialogForTesting() const {
  return !!dialog_;
}

void TabModalDialogManager::ClickDialogButtonForTesting(
    bool accept,
    const std::u16string& user_input) {
  DCHECK(!!dialog_);
  CloseDialog(DismissalCause::kDialogButtonClicked, accept, user_input);
}

void TabModalDialogManager::SetDialogDismissedCallbackForTesting(
    DialogDismissedCallback callback) {
  dialog_dismissed_ = std::move(callback);
}

void TabModalDialogManager::RunJavaScriptDialog(
    content::WebContents* alerting_web_contents,
    content::RenderFrameHost* render_frame_host,
    content::JavaScriptDialogType dialog_type,
    const std::u16string& message_text,
    const std::u16string& default_prompt_text,
    DialogClosedCallback callback,
    bool* did_suppress_message) {
  DCHECK_EQ(alerting_web_contents,
            content::WebContents::FromRenderFrameHost(render_frame_host));

  content::WebContents* web_contents = WebContentsObserver::web_contents();

  // Close any dialog already showing.
  CloseDialog(DismissalCause::kSubsequentDialogShown, false, std::u16string());

  bool make_pending = false;
  if (!delegate_->IsWebContentsForemost() &&
      !content::DevToolsAgentHost::IsDebuggerAttached(web_contents)) {
    static const char kDialogSuppressedConsoleMessageFormat[] =
        "A window.%s() dialog generated by this page was suppressed "
        "because this page is not the active tab of the front window. "
        "Please make sure your dialogs are triggered by user interactions "
        "to avoid this situation. https://www.chromestatus.com/feature/%s";

    switch (dialog_type) {
      case content::JAVASCRIPT_DIALOG_TYPE_ALERT: {
        // When an alert fires in the background, make the callback so that the
        // render process can continue.
        std::move(callback).Run(true, std::u16string());
        callback.Reset();

        delegate_->SetTabNeedsAttention(true);

        make_pending = true;
        break;
      }
      case content::JAVASCRIPT_DIALOG_TYPE_CONFIRM: {
        *did_suppress_message = true;
        render_frame_host->AddMessageToConsole(
            blink::mojom::ConsoleMessageLevel::kWarning,
            base::StringPrintf(kDialogSuppressedConsoleMessageFormat, "confirm",
                               "5140698722467840"));
        return;
      }
      case content::JAVASCRIPT_DIALOG_TYPE_PROMPT: {
        *did_suppress_message = true;
        render_frame_host->AddMessageToConsole(
            blink::mojom::ConsoleMessageLevel::kWarning,
            base::StringPrintf(kDialogSuppressedConsoleMessageFormat, "prompt",
                               "5637107137642496"));
        return;
      }
    }
  }

  // Enforce sane sizes. ElideRectangleString breaks horizontally, which isn't
  // strictly needed, but it restricts the vertical size, which is crucial.
  // This gives about 2000 characters, which is about the same as the
  // AppModalDialogManager provides, but allows no more than 24 lines.
  const int kMessageTextMaxRows = 24;
  const int kMessageTextMaxCols = 80;
  const size_t kDefaultPromptMaxSize = 2000;
  std::u16string truncated_message_text;
  gfx::ElideRectangleString(message_text, kMessageTextMaxRows,
                            kMessageTextMaxCols, false,
                            &truncated_message_text);
  std::u16string truncated_default_prompt_text;
  gfx::ElideString(default_prompt_text, kDefaultPromptMaxSize,
                   &truncated_default_prompt_text);

  std::u16string title = GetAppModalDialogManager()->GetTitle(
      alerting_web_contents, render_frame_host->GetLastCommittedOrigin());
  dialog_callback_ = std::move(callback);
  dialog_type_ = dialog_type;
  if (make_pending) {
    DCHECK(!dialog_);
    pending_dialog_ = base::BindOnce(
        &TabModalDialogManagerDelegate::CreateNewDialog,
        base::Unretained(delegate_.get()), alerting_web_contents, title,
        dialog_type, truncated_message_text, truncated_default_prompt_text,
        base::BindOnce(&TabModalDialogManager::CloseDialog,
                       base::Unretained(this),
                       DismissalCause::kDialogButtonClicked),
        base::BindOnce(&TabModalDialogManager::CloseDialog,
                       base::Unretained(this), DismissalCause::kDialogClosed,
                       false, std::u16string()));
  } else {
    DCHECK(!pending_dialog_);
    dialog_ = delegate_->CreateNewDialog(
        alerting_web_contents, title, dialog_type, truncated_message_text,
        truncated_default_prompt_text,
        base::BindOnce(&TabModalDialogManager::CloseDialog,
                       base::Unretained(this),
                       DismissalCause::kDialogButtonClicked),
        base::BindOnce(&TabModalDialogManager::CloseDialog,
                       base::Unretained(this), DismissalCause::kDialogClosed,
                       false, std::u16string()));
  }

  delegate_->WillRunDialog();

  // Message suppression is something that we don't give the user a checkbox
  // for any more. It was useful back in the day when dialogs were app-modal
  // and clicking the checkbox was the only way to escape a loop that the page
  // was doing, but now the user can just close the page.
  *did_suppress_message = false;

  if (!dialog_shown_.is_null())
    std::move(dialog_shown_).Run();
}

void TabModalDialogManager::RunBeforeUnloadDialog(
    content::WebContents* web_contents,
    content::RenderFrameHost* render_frame_host,
    bool is_reload,
    DialogClosedCallback callback) {
  DCHECK_EQ(web_contents,
            content::WebContents::FromRenderFrameHost(render_frame_host));

  // onbeforeunload dialogs are always handled with an app-modal dialog, because
  // - they are critical to the user not losing data
  // - they can be requested for tabs that are not foremost
  // - they can be requested for many tabs at the same time
  // and therefore auto-dismissal is inappropriate for them.

  return GetAppModalDialogManager()->RunBeforeUnloadDialogWithOptions(
      web_contents, render_frame_host, is_reload, delegate_->IsApp(),
      std::move(callback));
}

bool TabModalDialogManager::HandleJavaScriptDialog(
    content::WebContents* web_contents,
    bool accept,
    const std::u16string* prompt_override) {
  if (dialog_ || pending_dialog_) {
    CloseDialog(DismissalCause::kHandleDialogCalled, accept,
                prompt_override ? *prompt_override : dialog_->GetUserInput());
    return true;
  }

  // Handle any app-modal dialogs being run by the app-modal dialog system.
  return GetAppModalDialogManager()->HandleJavaScriptDialog(
      web_contents, accept, prompt_override);
}

void TabModalDialogManager::CancelDialogs(content::WebContents* web_contents,
                                          bool reset_state) {
  CloseDialog(DismissalCause::kCancelDialogsCalled, false, std::u16string());

  // Cancel any app-modal dialogs being run by the app-modal dialog system.
  return GetAppModalDialogManager()->CancelDialogs(web_contents, reset_state);
}

void TabModalDialogManager::OnVisibilityChanged(
    content::Visibility visibility) {
  if (visibility == content::Visibility::HIDDEN) {
    HandleTabSwitchAway(DismissalCause::kTabHidden);
  } else if (pending_dialog_) {
    dialog_ = std::move(pending_dialog_).Run();
    pending_dialog_.Reset();
    delegate_->SetTabNeedsAttention(false);
  }
}

void TabModalDialogManager::DidStartNavigation(
    content::NavigationHandle* navigation_handle) {
  if (!navigation_handle->IsInPrimaryMainFrame())
    return;

  // Close the dialog if the user started a new navigation. This allows reloads
  // and history navigations to proceed.
  CloseDialog(DismissalCause::kTabNavigated, false, std::u16string());
}

TabModalDialogManager::TabModalDialogManager(
    content::WebContents* web_contents,
    std::unique_ptr<TabModalDialogManagerDelegate> delegate)
    : content::WebContentsObserver(web_contents),
      content::WebContentsUserData<TabModalDialogManager>(*web_contents),
      delegate_(std::move(delegate)) {}

void TabModalDialogManager::LogDialogDismissalCause(DismissalCause cause) {
  if (dialog_dismissed_)
    std::move(dialog_dismissed_).Run(cause);

  // Log to UKM.
  //
  // Note that this will return the outermost WebContents, not necessarily the
  // WebContents that had the alert call in it. For 99.9999% of cases they're
  // the same, but for instances like the <webview> tag in extensions and PDF
  // files that alert they may differ.
  ukm::SourceId source_id = WebContentsObserver::web_contents()
                                ->GetPrimaryMainFrame()
                                ->GetPageUkmSourceId();
  if (source_id != ukm::kInvalidSourceId) {
    ukm::builders::AbusiveExperienceHeuristic_JavaScriptDialog(source_id)
        .SetDismissalCause(static_cast<int64_t>(cause))
        .Record(ukm::UkmRecorder::Get());
  }
}

void TabModalDialogManager::HandleTabSwitchAway(DismissalCause cause) {
  if (!dialog_ || content::DevToolsAgentHost::IsDebuggerAttached(
                      WebContentsObserver::web_contents())) {
    return;
  }

  if (dialog_type_ == content::JAVASCRIPT_DIALOG_TYPE_ALERT) {
    // When the user switches tabs, make the callback so that the render process
    // can continue.
    if (dialog_callback_) {
      std::move(dialog_callback_).Run(true, std::u16string());
      dialog_callback_.Reset();
    }
  } else {
    CloseDialog(cause, false, std::u16string());
  }
}

void TabModalDialogManager::CloseDialog(DismissalCause cause,
                                        bool success,
                                        const std::u16string& user_input) {
  if (!dialog_ && !pending_dialog_)
    return;

  LogDialogDismissalCause(cause);

  // CloseDialog() can be called two ways. It can be called from within
  // TabModalDialogManager, in which case the dialog needs to be closed.
  // However, it can also be called, bound, from the JavaScriptDialog. In that
  // case, the dialog is already closing, so the JavaScriptDialog doesn't need
  // to be told to close.
  //
  // Using the |cause| to distinguish a call from JavaScriptDialog vs from
  // within TabModalDialogManager is a bit hacky, but is the simplest way.
  if (dialog_ && cause != DismissalCause::kDialogButtonClicked &&
      cause != DismissalCause::kDialogClosed)
    dialog_->CloseDialogWithoutCallback();

  // If there is a callback, call it. There might not be one, if a tab-modal
  // alert() dialog is showing.
  if (dialog_callback_)
    std::move(dialog_callback_).Run(success, user_input);

  // If there's a pending dialog, then the tab is still in the "needs attention"
  // state; clear it out. However, if the tab was switched out, the turning off
  // of the "needs attention" state was done in OnTabStripModelChanged()
  // SetTabNeedsAttention won't work, so don't call it.
  if (pending_dialog_ && cause != DismissalCause::kTabSwitchedOut &&
      cause != DismissalCause::kTabHelperDestroyed) {
    delegate_->SetTabNeedsAttention(false);
  }

  dialog_.reset();
  pending_dialog_.Reset();
  dialog_callback_.Reset();

  delegate_->DidCloseDialog();
}

WEB_CONTENTS_USER_DATA_KEY_IMPL(TabModalDialogManager);

}  // namespace javascript_dialogs
