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

#include "ash/public/cpp/test/test_system_tray_client.h"
#include "ash/system/channel_indicator/channel_indicator_quick_settings_view.h"
#include "ash/system/unified/quick_settings_header.h"
#include "ash/system/unified/unified_system_tray_controller.h"
#include "ash/system/unified/unified_system_tray_model.h"
#include "ash/test/ash_test_base.h"
#include "ash/test/pixel/ash_pixel_differ.h"
#include "ash/test/pixel/ash_pixel_test_helper.h"
#include "ash/test_shell_delegate.h"
#include "base/memory/raw_ptr.h"
#include "components/version_info/channel.h"
#include "ui/views/widget/widget.h"

namespace ash {

class ChannelIndicatorQuickSettingsViewPixelTest
    : public AshTestBase,
      public testing::WithParamInterface</*enable_system_blur=*/bool> {
 public:
  ChannelIndicatorQuickSettingsViewPixelTest() = default;
  ChannelIndicatorQuickSettingsViewPixelTest(
      const ChannelIndicatorQuickSettingsViewPixelTest&) = delete;
  ChannelIndicatorQuickSettingsViewPixelTest& operator=(
      const ChannelIndicatorQuickSettingsViewPixelTest&) = delete;
  ~ChannelIndicatorQuickSettingsViewPixelTest() override = default;

  // AshTestBase:
  void SetUp() override {
    // Install a test delegate to allow overriding channel version.
    auto delegate = std::make_unique<TestShellDelegate>();
    delegate->set_channel(version_info::Channel::BETA);
    set_shell_delegate(std::move(delegate));
    AshTestBase::SetUp();

    GetSystemTrayClient()->set_user_feedback_enabled(true);

    // Place the view in a large views::Widget so the buttons are clickable.
    widget_ = CreateFramelessTestWidget();
    widget_->SetFullscreen(true);
    // Implicitly instantiate the view by creating the quick settings header.
    model_ = base::MakeRefCounted<UnifiedSystemTrayModel>(nullptr);
    controller_ = std::make_unique<UnifiedSystemTrayController>(model_.get());
    auto header = std::make_unique<QuickSettingsHeader>(controller_.get());
    header_ = header.get();
    widget_->SetContentsView(std::move(header));
  }

  std::optional<pixel_test::InitParams> CreatePixelTestInitParams()
      const override {
    pixel_test::InitParams init_params;
    init_params.system_blur_enabled = GetParam();
    return init_params;
  }

  void TearDown() override {
    header_ = nullptr;
    controller_.reset();
    model_.reset();
    widget_.reset();
    AshTestBase::TearDown();
  }

  QuickSettingsHeader* header() { return header_; }
  ChannelIndicatorQuickSettingsView* view() {
    return header()->channel_view_for_test();
  }

 private:
  scoped_refptr<UnifiedSystemTrayModel> model_;
  std::unique_ptr<UnifiedSystemTrayController> controller_;
  std::unique_ptr<views::Widget> widget_;
  raw_ptr<QuickSettingsHeader> header_ = nullptr;
};

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    ChannelIndicatorQuickSettingsViewPixelTest,
    testing::Bool());

// Verifies the UI when the feedback button is visible.
TEST_P(ChannelIndicatorQuickSettingsViewPixelTest, FeedbackButtonVisible) {
  // Basic verification that buttons are visible before taking screenshot.
  ASSERT_TRUE(header()->GetVisible());
  ASSERT_TRUE(view());
  ASSERT_TRUE(view()->version_button_for_test());
  ASSERT_TRUE(view()->version_button_for_test()->GetVisible());
  ASSERT_TRUE(view()->feedback_button_for_test());
  ASSERT_TRUE(view()->feedback_button_for_test()->GetVisible());

  // Don't capture any part of the UI except for
  // `ChannelIndicatorQuickSettingsView`.
  EXPECT_TRUE(GetPixelDiffer()->CompareUiComponentsOnPrimaryScreen(
      GenerateScreenshotName("feedback_button_visible"),
      /*revision_number=*/pixel_test_helper()->IsSystemBlurEnabled() ? 13 : 0,
      view()));
}

}  // namespace ash
