// Copyright 2013 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 "chrome/browser/ui/browser.h"

#include "base/macros.h"
#include "build/chromeos_buildflags.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/ash/login/users/fake_chrome_user_manager.h"
#include "chrome/browser/prefs/incognito_mode_prefs.h"
#include "chrome/browser/ui/browser_command_controller.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/test/base/browser_with_test_window_test.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/session_manager/core/session_manager.h"
#include "components/user_manager/fake_user_manager.h"
#include "components/user_manager/scoped_user_manager.h"
#include "components/user_manager/user_names.h"
#include "components/zoom/zoom_controller.h"
#include "content/public/browser/render_widget_host_view.h"
#include "content/public/browser/site_instance.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/web_contents_tester.h"
#include "third_party/skia/include/core/SkColor.h"

using content::SiteInstance;
using content::WebContents;
using content::WebContentsTester;
using session_manager::SessionState;

class BrowserUnitTest : public BrowserWithTestWindowTest {
 public:
  BrowserUnitTest() {}
  ~BrowserUnitTest() override {}

  // Caller owns the memory.
  std::unique_ptr<WebContents> CreateTestWebContents() {
    return WebContentsTester::CreateTestWebContents(
        profile(), SiteInstance::Create(profile()));
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(BrowserUnitTest);
};

// Ensure crashed tabs are not reloaded when selected. crbug.com/232323
TEST_F(BrowserUnitTest, ReloadCrashedTab) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();

  // Start with a single foreground tab. |tab_strip_model| owns the memory.
  std::unique_ptr<WebContents> contents1 = CreateTestWebContents();
  content::WebContents* raw_contents1 = contents1.get();
  tab_strip_model->AppendWebContents(std::move(contents1), true);
  WebContentsTester::For(raw_contents1)->NavigateAndCommit(GURL("about:blank"));
  WebContentsTester::For(raw_contents1)->TestSetIsLoading(false);
  EXPECT_TRUE(tab_strip_model->IsTabSelected(0));
  EXPECT_FALSE(raw_contents1->IsLoading());

  // Add a second tab in the background.
  std::unique_ptr<WebContents> contents2 = CreateTestWebContents();
  content::WebContents* raw_contents2 = contents2.get();
  tab_strip_model->AppendWebContents(std::move(contents2), false);
  WebContentsTester::For(raw_contents2)->NavigateAndCommit(GURL("about:blank"));
  WebContentsTester::For(raw_contents2)->TestSetIsLoading(false);
  EXPECT_EQ(2, browser()->tab_strip_model()->count());
  EXPECT_TRUE(tab_strip_model->IsTabSelected(0));
  EXPECT_FALSE(raw_contents2->IsLoading());

  // Simulate the second tab crashing.
  WebContentsTester::For(raw_contents2)
      ->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);
  EXPECT_TRUE(raw_contents2->IsCrashed());

  // Selecting the second tab does not cause a load or clear the crash.
  tab_strip_model->ActivateTabAt(1, {TabStripModel::GestureType::kOther});
  EXPECT_TRUE(tab_strip_model->IsTabSelected(1));
  EXPECT_FALSE(raw_contents2->IsLoading());
  EXPECT_TRUE(raw_contents2->IsCrashed());
}

// This tests a workaround which is not necessary on Mac.
// https://crbug.com/719230
#if defined(OS_MAC)
#define MAYBE_SetBackgroundColorForNewTab DISABLED_SetBackgroundColorForNewTab
#else
#define MAYBE_SetBackgroundColorForNewTab SetBackgroundColorForNewTab
#endif
TEST_F(BrowserUnitTest, MAYBE_SetBackgroundColorForNewTab) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();

  std::unique_ptr<WebContents> contents1 = CreateTestWebContents();
  content::WebContents* raw_contents1 = contents1.get();
  tab_strip_model->AppendWebContents(std::move(contents1), true);
  WebContentsTester::For(raw_contents1)->NavigateAndCommit(GURL("about:blank"));
  WebContentsTester::For(raw_contents1)->TestSetIsLoading(false);

  raw_contents1->GetMainFrame()->GetView()->SetBackgroundColor(SK_ColorRED);

  // Add a second tab in the background.
  std::unique_ptr<WebContents> contents2 = CreateTestWebContents();
  content::WebContents* raw_contents2 = contents2.get();
  tab_strip_model->AppendWebContents(std::move(contents2), false);
  WebContentsTester::For(raw_contents2)->NavigateAndCommit(GURL("about:blank"));
  WebContentsTester::For(raw_contents2)->TestSetIsLoading(false);

  tab_strip_model->ActivateTabAt(1, {TabStripModel::GestureType::kOther});
  ASSERT_TRUE(raw_contents2->GetMainFrame()->GetView()->GetBackgroundColor());
  EXPECT_EQ(SK_ColorRED,
            *raw_contents2->GetMainFrame()->GetView()->GetBackgroundColor());
}

// Ensure the print command gets disabled when a tab crashes.
TEST_F(BrowserUnitTest, DisablePrintOnCrashedTab) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();

  std::unique_ptr<WebContents> contents = CreateTestWebContents();
  content::WebContents* raw_contents = contents.get();
  tab_strip_model->AppendWebContents(std::move(contents), true);
  WebContentsTester::For(raw_contents)->NavigateAndCommit(GURL("about:blank"));

  CommandUpdater* command_updater = browser()->command_controller();

  EXPECT_FALSE(raw_contents->IsCrashed());
  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_PRINT));
  EXPECT_TRUE(chrome::CanPrint(browser()));

  WebContentsTester::For(raw_contents)
      ->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);

  EXPECT_TRUE(raw_contents->IsCrashed());
  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_PRINT));
  EXPECT_FALSE(chrome::CanPrint(browser()));
}

// Ensure the zoom-in and zoom-out commands get disabled when a tab crashes.
TEST_F(BrowserUnitTest, DisableZoomOnCrashedTab) {
  TabStripModel* tab_strip_model = browser()->tab_strip_model();

  std::unique_ptr<WebContents> contents = CreateTestWebContents();
  content::WebContents* raw_contents = contents.get();
  tab_strip_model->AppendWebContents(std::move(contents), true);
  WebContentsTester::For(raw_contents)->NavigateAndCommit(GURL("about:blank"));
  zoom::ZoomController* zoom_controller =
      zoom::ZoomController::FromWebContents(raw_contents);
  EXPECT_TRUE(
      zoom_controller->SetZoomLevel(zoom_controller->GetDefaultZoomLevel()));

  CommandUpdater* command_updater = browser()->command_controller();

  EXPECT_TRUE(zoom_controller->IsAtDefaultZoom());
  EXPECT_FALSE(raw_contents->IsCrashed());
  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_ZOOM_PLUS));
  EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_ZOOM_MINUS));
  EXPECT_TRUE(chrome::CanZoomIn(raw_contents));
  EXPECT_TRUE(chrome::CanZoomOut(raw_contents));

  WebContentsTester::For(raw_contents)
      ->SetIsCrashed(base::TERMINATION_STATUS_PROCESS_CRASHED, -1);

  EXPECT_TRUE(raw_contents->IsCrashed());
  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_ZOOM_PLUS));
  EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_ZOOM_MINUS));
  EXPECT_FALSE(chrome::CanZoomIn(raw_contents));
  EXPECT_FALSE(chrome::CanZoomOut(raw_contents));
}

TEST_F(BrowserUnitTest, CreateBrowserFailsIfProfileDisallowsBrowserWindows) {
  TestingProfile::Builder profile_builder;
  profile_builder.DisallowBrowserWindows();
  std::unique_ptr<TestingProfile> test_profile = profile_builder.Build();
  TestingProfile::Builder otr_profile_builder;
  otr_profile_builder.DisallowBrowserWindows();
  otr_profile_builder.BuildIncognito(test_profile.get());

  // Verify creating browser fails in both original and OTR version of the
  // profile.
  EXPECT_EQ(Browser::CreationStatus::kErrorProfileUnsuitable,
            Browser::GetCreationStatusForProfile(test_profile.get()));
  EXPECT_EQ(Browser::CreationStatus::kErrorProfileUnsuitable,
            Browser::GetCreationStatusForProfile(
                test_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true)));
}

// Tests BrowserCreate() when Incognito mode is disabled.
TEST_F(BrowserUnitTest, CreateBrowserWithIncognitoModeDisabled) {
  IncognitoModePrefs::SetAvailability(profile()->GetPrefs(),
                                      IncognitoModePrefs::DISABLED);

  // Creating a browser window in OTR profile should fail if incognito is
  // disabled.
  EXPECT_EQ(Browser::CreationStatus::kErrorProfileUnsuitable,
            Browser::GetCreationStatusForProfile(
                profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true)));

  // Verify creating a browser in the original profile succeeds.
  Browser::CreateParams create_params(profile(), false);
  std::unique_ptr<BrowserWindow> test_window(CreateBrowserWindow());
  create_params.window = test_window.get();
  std::unique_ptr<Browser> test_browser(Browser::Create(create_params));
  EXPECT_TRUE(test_browser);
}

// Tests BrowserCreate() when Incognito mode is forced.
TEST_F(BrowserUnitTest, CreateBrowserWithIncognitoModeForced) {
  IncognitoModePrefs::SetAvailability(profile()->GetPrefs(),
                                      IncognitoModePrefs::FORCED);

  // Creating a browser window in the original profile should fail if incognito
  // is forced.
  EXPECT_EQ(Browser::CreationStatus::kErrorProfileUnsuitable,
            Browser::GetCreationStatusForProfile(profile()));

  // Creating a browser in OTR test profile should succeed.
  Browser::CreateParams off_the_record_create_params(
      profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true), false);
  std::unique_ptr<BrowserWindow> test_window(CreateBrowserWindow());
  off_the_record_create_params.window = test_window.get();
  std::unique_ptr<Browser> otr_browser(
      Browser::Create(off_the_record_create_params));
  EXPECT_TRUE(otr_browser);
}

// Tests BrowserCreate() with not restrictions on incognito mode.
TEST_F(BrowserUnitTest, CreateBrowserWithIncognitoModeEnabled) {
  ASSERT_EQ(IncognitoModePrefs::ENABLED,
            IncognitoModePrefs::GetAvailability(profile()->GetPrefs()));

  // Creating a browser in the original test profile should succeed.
  Browser::CreateParams create_params(profile(), false);
  std::unique_ptr<BrowserWindow> test_window(CreateBrowserWindow());
  create_params.window = test_window.get();
  std::unique_ptr<Browser> test_browser(Browser::Create(create_params));
  EXPECT_TRUE(test_browser);

  // Creating a browser in OTR test profile should succeed.
  Browser::CreateParams off_the_record_create_params(
      profile()->GetPrimaryOTRProfile(/*create_if_needed=*/true), false);
  std::unique_ptr<BrowserWindow> otr_test_window(CreateBrowserWindow());
  off_the_record_create_params.window = otr_test_window.get();
  std::unique_ptr<Browser> otr_browser(
      Browser::Create(off_the_record_create_params));
  EXPECT_TRUE(otr_browser);
}

#if BUILDFLAG(IS_CHROMEOS_ASH)
TEST_F(BrowserUnitTest, CreateBrowserDuringKioskSplashScreen) {
  session_manager::SessionManager session_manager;

  // Setting up user manager state to be in kiosk mode:
  // Creating a new user manager.
  auto* user_manager = new ash::FakeChromeUserManager();
  user_manager::ScopedUserManager manager{
      std::unique_ptr<user_manager::UserManager>(user_manager)};
  const user_manager::User* user =
      user_manager->AddKioskAppUser(AccountId::FromUserEmail("fake_user@test"));
  user_manager->LoginUser(user->GetAccountId());

  TestingProfile profile;

  session_manager.SetSessionState(SessionState::LOGIN_PRIMARY);
  // Browser should not be created during login session state.
  EXPECT_EQ(Browser::CreationStatus::kErrorLoadingKiosk,
            Browser::GetCreationStatusForProfile(&profile));

  Browser::CreateParams create_params = Browser::CreateParams(&profile, false);
  std::unique_ptr<BrowserWindow> window = CreateBrowserWindow();
  create_params.window = window.get();
  session_manager.SetSessionState(SessionState::ACTIVE);
  std::unique_ptr<Browser> test_browser(Browser::Create(create_params));
  // Normal flow, creation succeeds.
  EXPECT_TRUE(test_browser);
}
#endif

class BrowserBookmarkBarTest : public BrowserWithTestWindowTest {
 public:
  BrowserBookmarkBarTest() {}
  ~BrowserBookmarkBarTest() override {}

 protected:
  BookmarkBar::State window_bookmark_bar_state() const {
    return static_cast<BookmarkBarStateTestBrowserWindow*>(browser()->window())
        ->bookmark_bar_state();
  }

  // BrowserWithTestWindowTest:
  void SetUp() override {
    BrowserWithTestWindowTest::SetUp();
    static_cast<BookmarkBarStateTestBrowserWindow*>(browser()->window())
        ->set_browser(browser());
  }

  std::unique_ptr<BrowserWindow> CreateBrowserWindow() override {
    return std::make_unique<BookmarkBarStateTestBrowserWindow>();
  }

 private:
  class BookmarkBarStateTestBrowserWindow : public TestBrowserWindow {
   public:
    BookmarkBarStateTestBrowserWindow()
        : browser_(nullptr), bookmark_bar_state_(BookmarkBar::HIDDEN) {}
    ~BookmarkBarStateTestBrowserWindow() override {}

    void set_browser(Browser* browser) { browser_ = browser; }

    BookmarkBar::State bookmark_bar_state() const {
      return bookmark_bar_state_;
    }

   private:
    // TestBrowserWindow:
    void BookmarkBarStateChanged(
        BookmarkBar::AnimateChangeType change_type) override {
      bookmark_bar_state_ = browser_->bookmark_bar_state();
      TestBrowserWindow::BookmarkBarStateChanged(change_type);
    }

    void OnActiveTabChanged(content::WebContents* old_contents,
                            content::WebContents* new_contents,
                            int index,
                            int reason) override {
      bookmark_bar_state_ = browser_->bookmark_bar_state();
      TestBrowserWindow::OnActiveTabChanged(old_contents, new_contents, index,
                                            reason);
    }

    Browser* browser_;  // Weak ptr.
    BookmarkBar::State bookmark_bar_state_;

    DISALLOW_COPY_AND_ASSIGN(BookmarkBarStateTestBrowserWindow);
  };

  DISALLOW_COPY_AND_ASSIGN(BrowserBookmarkBarTest);
};

// Ensure bookmark bar states in Browser and BrowserWindow are in sync after
// Browser::ActiveTabChanged() calls BrowserWindow::OnActiveTabChanged().
TEST_F(BrowserBookmarkBarTest, StateOnActiveTabChanged) {
  ASSERT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
  ASSERT_EQ(BookmarkBar::HIDDEN, window_bookmark_bar_state());

  GURL ntp_url("chrome://newtab");
  GURL non_ntp_url("http://foo");

  // Open a tab to NTP.
  AddTab(browser(), ntp_url);
  EXPECT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
  EXPECT_EQ(BookmarkBar::HIDDEN, window_bookmark_bar_state());

  // Navigate 1st tab to a non-NTP URL.
  NavigateAndCommitActiveTab(non_ntp_url);
  EXPECT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
  EXPECT_EQ(BookmarkBar::HIDDEN, window_bookmark_bar_state());

  // Open a tab to NTP at index 0.
  AddTab(browser(), ntp_url);
  EXPECT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
  EXPECT_EQ(BookmarkBar::HIDDEN, window_bookmark_bar_state());

  // Activate the 2nd tab which is non-NTP.
  browser()->tab_strip_model()->ActivateTabAt(
      1, {TabStripModel::GestureType::kOther});
  EXPECT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state());
  EXPECT_EQ(BookmarkBar::HIDDEN, window_bookmark_bar_state());

  // Toggle bookmark bar while 2nd tab (non-NTP) is active.
  chrome::ToggleBookmarkBar(browser());
  EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state());
  EXPECT_EQ(BookmarkBar::SHOW, window_bookmark_bar_state());

  // Activate the 1st tab which is NTP.
  browser()->tab_strip_model()->ActivateTabAt(
      0, {TabStripModel::GestureType::kOther});
  EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state());
  EXPECT_EQ(BookmarkBar::SHOW, window_bookmark_bar_state());

  // Activate the 2nd tab which is non-NTP.
  browser()->tab_strip_model()->ActivateTabAt(
      1, {TabStripModel::GestureType::kOther});
  EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state());
  EXPECT_EQ(BookmarkBar::SHOW, window_bookmark_bar_state());
}

class GuestBrowserUnitTest : public BrowserUnitTest,
                             public testing::WithParamInterface<bool> {
 public:
  GuestBrowserUnitTest() : is_ephemeral_(GetParam()) {
    // Change the value if Ephemeral is not supported.
    is_ephemeral_ &=
        TestingProfile::SetScopedFeatureListForEphemeralGuestProfiles(
            scoped_feature_list_, is_ephemeral_);
  }

  bool is_ephemeral() const { return is_ephemeral_; }

 private:
  bool is_ephemeral_;
  base::test::ScopedFeatureList scoped_feature_list_;
};

// Tests that Browser::Create creates a guest session browser for appropriate
// OTR/non-OTR type for old and ephemeral Guest profiles.
TEST_P(GuestBrowserUnitTest, CreateGuestSessionBrowser) {
  TestingProfile* test_profile = profile_manager()->CreateGuestProfile();
  TestingProfile::Builder otr_profile_builder;
  otr_profile_builder.SetGuestSession();
  Profile* guest_profile = nullptr;

  if (is_ephemeral()) {
    // Try creating an OTR profile for ephemeral Guest profile, it should fail.
    EXPECT_FALSE(otr_profile_builder.BuildIncognito(test_profile));
    guest_profile = test_profile;
  } else {
    // Try creating a browser in original guest profile - it should fail.
    EXPECT_EQ(Browser::CreationStatus::kErrorProfileUnsuitable,
              Browser::GetCreationStatusForProfile(test_profile));

    // Create OTR profile for the Guest profile.
    EXPECT_TRUE(otr_profile_builder.BuildIncognito(test_profile));
    guest_profile =
        test_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true);
  }

  // Creating a browser should succeed.
  Browser::CreateParams create_params =
      Browser::CreateParams(guest_profile, false);
  std::unique_ptr<BrowserWindow> test_window = CreateBrowserWindow();
  create_params.window = test_window.get();
  std::unique_ptr<Browser> browser =
      std::unique_ptr<Browser>(Browser::Create(create_params));
  EXPECT_TRUE(browser);
}

INSTANTIATE_TEST_SUITE_P(AllGuestTypes,
                         GuestBrowserUnitTest,
                         /*is_ephemeral=*/testing::Bool());
