// 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 "ui/views/controls/menu/menu_model_adapter.h"
#include "base/callback.h"
#include "base/location.h"
#include "base/memory/raw_ptr.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/current_thread.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread_task_runner_handle.h"
#include "chrome/browser/ui/views/test/view_event_test_base.h"
#include "chrome/test/base/interactive_test_utils.h"
#include "chrome/test/base/ui_test_utils.h"
#include "ui/base/models/menu_model.h"
#include "ui/base/test/ui_controls.h"
#include "ui/views/controls/button/menu_button.h"
#include "ui/views/controls/menu/menu_controller.h"
#include "ui/views/controls/menu/menu_item_view.h"
#include "ui/views/controls/menu/menu_runner.h"
#include "ui/views/controls/menu/submenu_view.h"
#include "ui/views/test/menu_test_utils.h"
#include "ui/views/widget/root_view.h"
#include "ui/views/widget/widget.h"

namespace {

const int kTopMenuBaseId = 100;
const int kSubMenuBaseId = 200;

// Implement most of the ui::MenuModel pure virtual methods for subclasses
//
// Exceptions:
//  virtual int GetItemCount() const = 0;
//  virtual ItemType GetTypeAt(int index) const = 0;
//  virtual int GetCommandIdAt(int index) const = 0;
//  virtual std::u16string GetLabelAt(int index) const = 0;
class CommonMenuModel : public ui::MenuModel {
 public:
  CommonMenuModel() {
  }

  CommonMenuModel(const CommonMenuModel&) = delete;
  CommonMenuModel& operator=(const CommonMenuModel&) = delete;

  ~CommonMenuModel() override {}

 protected:
  // ui::MenuModel implementation.
  bool HasIcons() const override { return false; }

  bool IsItemDynamicAt(int index) const override { return false; }

  bool GetAcceleratorAt(int index,
                        ui::Accelerator* accelerator) const override {
    return false;
  }

  ui::MenuSeparatorType GetSeparatorTypeAt(int index) const override {
    return ui::NORMAL_SEPARATOR;
  }

  bool IsItemCheckedAt(int index) const override { return false; }

  int GetGroupIdAt(int index) const override { return 0; }

  ui::ImageModel GetIconAt(int index) const override {
    return ui::ImageModel();
  }

  ui::ButtonMenuItemModel* GetButtonMenuItemAt(int index) const override {
    return nullptr;
  }

  bool IsEnabledAt(int index) const override { return true; }

  ui::MenuModel* GetSubmenuModelAt(int index) const override { return nullptr; }

  void ActivatedAt(int index) override {}
};

class SubMenuModel : public CommonMenuModel {
 public:
  SubMenuModel()
      : showing_(false) {
  }

  SubMenuModel(const SubMenuModel&) = delete;
  SubMenuModel& operator=(const SubMenuModel&) = delete;

  ~SubMenuModel() override {}

  bool showing() const {
    return showing_;
  }

 private:
  // ui::MenuModel implementation.
  int GetItemCount() const override { return 1; }

  ItemType GetTypeAt(int index) const override { return TYPE_COMMAND; }

  int GetCommandIdAt(int index) const override {
    return index + kSubMenuBaseId;
  }

  std::u16string GetLabelAt(int index) const override { return u"Item"; }

  void MenuWillShow() override { showing_ = true; }

  // Called when the menu is about to close.
  void MenuWillClose() override { showing_ = false; }

  bool showing_;
};

class TopMenuModel : public CommonMenuModel {
 public:
  TopMenuModel() {
  }

  TopMenuModel(const TopMenuModel&) = delete;
  TopMenuModel& operator=(const TopMenuModel&) = delete;

  ~TopMenuModel() override {}

  bool IsSubmenuShowing() {
    return sub_menu_model_.showing();
  }

 private:
  // ui::MenuModel implementation.
  int GetItemCount() const override { return 1; }

  ItemType GetTypeAt(int index) const override { return TYPE_SUBMENU; }

  int GetCommandIdAt(int index) const override {
    return index + kTopMenuBaseId;
  }

  std::u16string GetLabelAt(int index) const override { return u"submenu"; }

  MenuModel* GetSubmenuModelAt(int index) const override {
    return &sub_menu_model_;
  }

  mutable SubMenuModel sub_menu_model_;
};

}  // namespace

class MenuModelAdapterTest : public ViewEventTestBase {
 public:
  MenuModelAdapterTest() = default;
  ~MenuModelAdapterTest() override = default;

  // ViewEventTestBase implementation.

  void SetUp() override {
    ViewEventTestBase::SetUp();

    menu_ = menu_model_adapter_.CreateMenu();
    menu_runner_ = std::make_unique<views::MenuRunner>(
        menu_, views::MenuRunner::HAS_MNEMONICS);
  }

  void TearDown() override {
    menu_runner_.reset();

    ViewEventTestBase::TearDown();
  }

  std::unique_ptr<views::View> CreateContentsView() override {
    auto button = std::make_unique<views::MenuButton>(
        base::BindRepeating(&MenuModelAdapterTest::ButtonPressed,
                            base::Unretained(this)),
        u"Menu Adapter Test");
    button_ = button.get();
    return button;
  }

  gfx::Size GetPreferredSizeForContents() const override {
    return button_->GetPreferredSize();
  }

  // ViewEventTestBase implementation
  void DoTestOnMessageLoop() override {
    Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step1));
  }

  // Open the submenu.
  void Step1() {
    views::test::DisableMenuClosureAnimations();
    views::SubmenuView* topmenu = menu_->GetSubmenu();
    ASSERT_TRUE(topmenu);
    ASSERT_TRUE(topmenu->IsShowing());
    ASSERT_FALSE(top_menu_model_.IsSubmenuShowing());

    // Click the first item to open the submenu.
    views::MenuItemView* item = topmenu->GetMenuItemAt(0);
    ASSERT_TRUE(item);
    Click(item, CreateEventTask(this, &MenuModelAdapterTest::Step2));
  }

  // Rebuild the menu which should close the submenu.
  void Step2() {
    views::SubmenuView* topmenu = menu_->GetSubmenu();
    ASSERT_TRUE(topmenu);
    ASSERT_TRUE(topmenu->IsShowing());
    ASSERT_TRUE(top_menu_model_.IsSubmenuShowing());

    menu_model_adapter_.BuildMenu(menu_);

    ASSERT_TRUE(base::CurrentUIThread::IsSet());
    base::ThreadTaskRunnerHandle::Get()->PostTask(
        FROM_HERE, CreateEventTask(this, &MenuModelAdapterTest::Step3));
  }

  // Verify that the submenu MenuModel received the close callback
  // and close the menu.
  void Step3() {
    views::SubmenuView* topmenu = menu_->GetSubmenu();
    ASSERT_TRUE(topmenu);
    ASSERT_TRUE(topmenu->IsShowing());
    ASSERT_FALSE(top_menu_model_.IsSubmenuShowing());

    // Click the button to exit the menu.
    Click(button_, CreateEventTask(this, &MenuModelAdapterTest::Step4));
  }

  // All done.
  void Step4() {
    views::SubmenuView* topmenu = menu_->GetSubmenu();
    views::test::WaitForMenuClosureAnimation();
    ASSERT_TRUE(topmenu);
    ASSERT_FALSE(topmenu->IsShowing());
    ASSERT_FALSE(top_menu_model_.IsSubmenuShowing());

    Done();
  }

 private:
  // Generate a mouse click on the specified view and post a new task.
  virtual void Click(views::View* view, base::OnceClosure next) {
    ui_test_utils::MoveMouseToCenterAndPress(
        view, ui_controls::LEFT, ui_controls::DOWN | ui_controls::UP,
        std::move(next));
  }

  void ButtonPressed() {
    menu_runner_->RunMenuAt(button_->GetWidget(), button_->button_controller(),
                            button_->GetBoundsInScreen(),
                            views::MenuAnchorPosition::kTopLeft,
                            ui::MENU_SOURCE_NONE);
  }

  raw_ptr<views::MenuButton> button_ = nullptr;
  TopMenuModel top_menu_model_;
  views::MenuModelAdapter menu_model_adapter_{&top_menu_model_};
  raw_ptr<views::MenuItemView> menu_ = nullptr;
  std::unique_ptr<views::MenuRunner> menu_runner_;
};

// If this flakes, disable and log details in http://crbug.com/523255.
VIEW_TEST(MenuModelAdapterTest, RebuildMenu)
