// Copyright (c) 2012 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 <stddef.h>

#include "base/bind.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/utf_string_conversions.h"
#include "chrome/browser/extensions/extension_apitest.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/app_modal/app_modal_dialog_queue.h"
#include "components/app_modal/javascript_app_modal_dialog.h"
#include "components/app_modal/native_app_modal_dialog.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/test/test_utils.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/process_manager.h"
#include "extensions/common/extension.h"

namespace extensions {

namespace {

void GetNextDialog(app_modal::NativeAppModalDialog** native_dialog) {
  DCHECK(native_dialog);
  *native_dialog = nullptr;
  app_modal::JavaScriptAppModalDialog* dialog =
      ui_test_utils::WaitForAppModalDialog();
  *native_dialog = dialog->native_dialog();
  ASSERT_TRUE(*native_dialog);
}

void CloseDialog() {
  app_modal::NativeAppModalDialog* dialog = nullptr;
  ASSERT_NO_FATAL_FAILURE(GetNextDialog(&dialog));
  dialog->CloseAppModalDialog();
}

void AcceptDialog() {
  app_modal::NativeAppModalDialog* dialog = nullptr;
  ASSERT_NO_FATAL_FAILURE(GetNextDialog(&dialog));
  dialog->AcceptAppModalDialog();
}

void CancelDialog() {
  app_modal::NativeAppModalDialog* dialog = nullptr;
  ASSERT_NO_FATAL_FAILURE(GetNextDialog(&dialog));
  dialog->CancelAppModalDialog();
}

void CheckAlertResult(const std::string& dialog_name,
                      size_t* call_count,
                      const base::Value* value) {
  ASSERT_TRUE(value) << dialog_name;
  ASSERT_TRUE(value->is_none());
  ++*call_count;
}

void CheckConfirmResult(const std::string& dialog_name,
                        bool expected_value,
                        size_t* call_count,
                        const base::Value* value) {
  ASSERT_TRUE(value) << dialog_name;
  bool current_value;
  ASSERT_TRUE(value->GetAsBoolean(&current_value)) << dialog_name;
  ASSERT_EQ(expected_value, current_value) << dialog_name;
  ++*call_count;
}

}  // namespace

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, AlertBasic) {
  ASSERT_TRUE(RunExtensionTest("alert")) << message_;

  const Extension* extension = GetSingleLoadedExtension();
  ExtensionHost* host = ProcessManager::Get(browser()->profile())
                            ->GetBackgroundHostForExtension(extension->id());
  ASSERT_TRUE(host);
  host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
      base::ASCIIToUTF16("alert('This should not crash.');"));

  ASSERT_NO_FATAL_FAILURE(CloseDialog());
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, AlertQueue) {
  ASSERT_TRUE(RunExtensionTest("alert")) << message_;

  const Extension* extension = GetSingleLoadedExtension();
  ExtensionHost* host = ProcessManager::Get(browser()->profile())
                            ->GetBackgroundHostForExtension(extension->id());
  ASSERT_TRUE(host);

  // Creates several dialogs at the same time.
  const size_t num_dialogs = 3;
  size_t call_count = 0;
  for (size_t i = 0; i != num_dialogs; ++i) {
    const std::string dialog_name = "Dialog #" + base::NumberToString(i) + ".";
    host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
        base::ASCIIToUTF16("alert('" + dialog_name + "');"),
        base::Bind(&CheckAlertResult, dialog_name,
                   base::Unretained(&call_count)));
  }

  // Closes these dialogs.
  for (size_t i = 0; i != num_dialogs; ++i) {
    ASSERT_NO_FATAL_FAILURE(AcceptDialog());
  }

  // All dialogs must be closed now.
  app_modal::AppModalDialogQueue* queue =
      app_modal::AppModalDialogQueue::GetInstance();
  ASSERT_TRUE(queue);
  EXPECT_FALSE(queue->HasActiveDialog());
  EXPECT_EQ(0, queue->end() - queue->begin());
  while (call_count < num_dialogs)
    ASSERT_NO_FATAL_FAILURE(content::RunAllPendingInMessageLoop());
}

IN_PROC_BROWSER_TEST_F(ExtensionApiTest, ConfirmQueue) {
  ASSERT_TRUE(RunExtensionTest("alert")) << message_;

  const Extension* extension = GetSingleLoadedExtension();
  ExtensionHost* host = ProcessManager::Get(browser()->profile())
                            ->GetBackgroundHostForExtension(extension->id());
  ASSERT_TRUE(host);

  // Creates several dialogs at the same time.
  const size_t num_accepted_dialogs = 3;
  const size_t num_cancelled_dialogs = 3;
  size_t call_count = 0;
  for (size_t i = 0; i != num_accepted_dialogs; ++i) {
    const std::string dialog_name =
        "Accepted dialog #" + base::NumberToString(i) + ".";
    host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
        base::ASCIIToUTF16("confirm('" + dialog_name + "');"),
        base::Bind(&CheckConfirmResult, dialog_name, true,
                   base::Unretained(&call_count)));
  }
  for (size_t i = 0; i != num_cancelled_dialogs; ++i) {
    const std::string dialog_name =
        "Cancelled dialog #" + base::NumberToString(i) + ".";
    host->host_contents()->GetMainFrame()->ExecuteJavaScriptForTests(
        base::ASCIIToUTF16("confirm('" + dialog_name + "');"),
        base::Bind(&CheckConfirmResult, dialog_name, false,
                   base::Unretained(&call_count)));
  }

  // Closes these dialogs.
  for (size_t i = 0; i != num_accepted_dialogs; ++i)
    ASSERT_NO_FATAL_FAILURE(AcceptDialog());
  for (size_t i = 0; i != num_cancelled_dialogs; ++i)
    ASSERT_NO_FATAL_FAILURE(CancelDialog());

  // All dialogs must be closed now.
  app_modal::AppModalDialogQueue* queue =
      app_modal::AppModalDialogQueue::GetInstance();
  ASSERT_TRUE(queue);
  EXPECT_FALSE(queue->HasActiveDialog());
  EXPECT_EQ(0, queue->end() - queue->begin());
  while (call_count < num_accepted_dialogs + num_cancelled_dialogs)
    ASSERT_NO_FATAL_FAILURE(content::RunAllPendingInMessageLoop());
}

}  // namespace extensions
