// Copyright 2018 The Chromium Authors
// 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_commands.h"

#include "base/path_service.h"
#include "base/task/current_thread.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "browser_commands.h"
#include "chrome/app/chrome_command_ids.h"
#include "chrome/browser/content_settings/cookie_settings_factory.h"
#include "chrome/browser/lifetime/browser_shutdown.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_list.h"
#include "chrome/browser/ui/browser_tabstrip.h"
#include "chrome/browser/ui/browser_window/public/browser_window_features.h"
#include "chrome/browser/ui/tabs/organization/tab_organization_service.h"
#include "chrome/browser/ui/tabs/organization/tab_organization_service_factory.h"
#include "chrome/browser/ui/tabs/organization/tab_organization_session.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/toasts/toast_controller.h"
#include "chrome/browser/ui/toasts/toast_features.h"
#include "chrome/browser/ui/ui_features.h"
#include "chrome/browser/ui/views/frame/browser_view.h"
#include "chrome/browser/ui/views/side_panel/side_panel_coordinator.h"
#include "chrome/browser/ui/views/side_panel/side_panel_entry_id.h"
#include "chrome/browser/ui/views/tab_search_bubble_host.h"
#include "chrome/browser/ui/webui/commerce/product_specifications_disclosure_dialog.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/commerce/core/mojom/product_specifications.mojom.h"
#include "components/commerce/core/pref_names.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/prefs/pref_service.h"
#include "components/ukm/test_ukm_recorder.h"
#include "content/public/common/content_paths.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "net/dns/mock_host_resolver.h"
#include "ui/base/ui_base_features.h"

namespace chrome {

class BrowserCommandsTest : public InProcessBrowserTest {
 public:
  BrowserCommandsTest() : https_server_(net::EmbeddedTestServer::TYPE_HTTPS) {
    feature_list_.InitWithFeatures(
        {
            features::kTabOrganization,
            features::kTabstripDeclutter,
            toast_features::kReadingListToast,
            toast_features::kLinkCopiedToast,
        },
        {});
  }

  base::test::ScopedFeatureList feature_list_;
  net::test_server::EmbeddedTestServer https_server_;

  void SetUpOnMainThread() override {
    host_resolver()->AddRule("*", "127.0.0.1");
    base::FilePath path;
    base::PathService::Get(content::DIR_TEST_DATA, &path);
    https_server_.SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
    https_server_.ServeFilesFromDirectory(path);
    https_server_.AddDefaultHandlers(GetChromeTestDataDir());
    ASSERT_TRUE(https_server_.Start());
  }

  static constexpr char kUrl[] = "chrome://version/";

  void AddAndReloadTabs(int tab_count) {
    for (int i = 0; i < tab_count; ++i) {
      ASSERT_TRUE(AddTabAtIndexToBrowser(browser(), i + 1, GURL(kUrl),
                                         ui::PAGE_TRANSITION_LINK, false));
    }

    // Add tabs to the selection (the last one created remains selected) and
    // trigger a reload command on all of them.
    for (int i = 0; i < tab_count - 1; ++i) {
      browser()->tab_strip_model()->SelectTabAt(i + 1);
    }
    EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_RELOAD));
    browser()->tab_strip_model()->CloseSelectedTabs();
  }

  void SetThirdPartyCookieBlocking(bool enabled) {
    browser()->profile()->GetPrefs()->SetInteger(
        prefs::kCookieControlsMode,
        static_cast<int>(
            enabled ? content_settings::CookieControlsMode::kBlockThirdParty
                    : content_settings::CookieControlsMode::kOff));
  }

  void CheckReloadBreakageMetrics(ukm::TestAutoSetUkmRecorder& ukm_recorder,
                                  size_t size,
                                  size_t index,
                                  bool blocked,
                                  bool settings_blocked) {
    auto entries = ukm_recorder.GetEntries(
        "ThirdPartyCookies.BreakageIndicator.UserReload",
        {"TPCBlocked", "TPCBlockedInSettings"});
    EXPECT_EQ(entries.size(), size);
    EXPECT_EQ(entries.at(index).metrics.at("TPCBlocked"), blocked);
    EXPECT_EQ(entries.at(index).metrics.at("TPCBlockedInSettings"),
              settings_blocked);
  }

  class ReloadObserver : public content::WebContentsObserver {
   public:
    ~ReloadObserver() override = default;

    int load_count() const { return load_count_; }
    void SetWebContents(content::WebContents* web_contents) {
      Observe(web_contents);
    }

    // content::WebContentsObserver
    void DidStartLoading() override { load_count_++; }

   private:
    int load_count_ = 0;
  };
};

// Verify that calling BookmarkCurrentTab() just after closing all tabs doesn't
// cause a crash. https://crbug.com/799668
IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, BookmarkCurrentTabAfterCloseTabs) {
  browser()->tab_strip_model()->CloseAllTabs();
  BookmarkCurrentTab(browser());
}

// Verify that all of selected tabs are refreshed after executing a reload
// command. https://crbug.com/862102
IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, ReloadSelectedTabs) {
  constexpr int kTabCount = 3;
  std::vector<ReloadObserver> watcher_vec(kTabCount);
  for (int i = 0; i < kTabCount; i++) {
    ASSERT_TRUE(AddTabAtIndexToBrowser(browser(), i + 1, GURL(kUrl),
                                       ui::PAGE_TRANSITION_LINK, false));
    content::WebContents* tab =
        browser()->tab_strip_model()->GetWebContentsAt(i + 1);
    watcher_vec[i].SetWebContents(tab);
  }

  for (ReloadObserver& watcher : watcher_vec) {
    EXPECT_EQ(0, watcher.load_count());
  }

  // Add two tabs to the selection (the last one created remains selected) and
  // trigger a reload command on all of them.
  for (int i = 0; i < kTabCount - 1; i++) {
    browser()->tab_strip_model()->SelectTabAt(i + 1);
  }
  EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_RELOAD));

  int load_sum = 0;
  for (ReloadObserver& watcher : watcher_vec) {
    load_sum += watcher.load_count();
  }
  EXPECT_EQ(kTabCount, load_sum);
}

// Check that the ThirdPartyCookieBreakageIndicator UKM is sent on Reload.
// Disabled because of crbug.com/1468528
IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, DISABLED_ReloadBreakageUKM) {
  ukm::TestAutoSetUkmRecorder ukm_recorder;
  content_settings::CookieSettings* settings =
      CookieSettingsFactory::GetForProfile(browser()->profile()).get();

  // Test simple reload measurements without 3PCB.
  SetThirdPartyCookieBlocking(false);
  EXPECT_FALSE(settings->ShouldBlockThirdPartyCookies());

  AddAndReloadTabs(1);
  CheckReloadBreakageMetrics(ukm_recorder, 1, 0, false, false);

  AddAndReloadTabs(1);
  CheckReloadBreakageMetrics(ukm_recorder, 2, 1, false, false);

  // Test that enabled 3PCB is correctly reflected in the metrics.
  SetThirdPartyCookieBlocking(true);
  EXPECT_TRUE(settings->ShouldBlockThirdPartyCookies());

  AddAndReloadTabs(1);
  CheckReloadBreakageMetrics(ukm_recorder, 3, 2, false, true);

  // Test that allow-listing is correctly reflected in the metrics.
  GURL origin(kUrl);
  settings->SetThirdPartyCookieSetting(origin,
                                       ContentSetting::CONTENT_SETTING_ALLOW);
  EXPECT_TRUE(settings->IsThirdPartyAccessAllowed(origin, nullptr));

  AddAndReloadTabs(1);
  CheckReloadBreakageMetrics(ukm_recorder, 4, 3, false, false);

  // Reload multiple tabs, all reloads are counted.
  AddAndReloadTabs(3);
  CheckReloadBreakageMetrics(ukm_recorder, 7, 4, false, false);
  CheckReloadBreakageMetrics(ukm_recorder, 7, 5, false, false);
  CheckReloadBreakageMetrics(ukm_recorder, 7, 6, false, false);

  // Load a page with an iframe and try to set a cross-site cookie inside of
  // that iframe.
  constexpr char host_a[] = "a.test";
  constexpr char host_b[] = "b.test";
  GURL main_url(https_server_.GetURL(host_a, "/iframe.html"));
  EXPECT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
  GURL page = https_server_.GetURL(
      host_b, "/set-cookie?thirdparty=1;SameSite=None;Secure");
  content::WebContents* web_contents =
      browser()->tab_strip_model()->GetActiveWebContents();
  EXPECT_TRUE(NavigateIframeToURL(web_contents, "test", page));

  // Reload the page with the cross-site iframe.
  EXPECT_TRUE(chrome::ExecuteCommand(browser(), IDC_RELOAD));

  // We should now observe a 3P cookie *actually* blocked.
  CheckReloadBreakageMetrics(ukm_recorder, 8, 7, true, true);
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, MoveTabsToNewWindow) {
  auto AddTabs = [](Browser* browser, unsigned int num_tabs) {
    for (unsigned int i = 0; i < num_tabs; ++i) {
      chrome::NewTab(browser);
    }
  };

  // Single Tab Move to New Window.
  // 1 (Current) + 1 (Added) = 2
  AddTabs(browser(), 1);
  std::vector<int> indices = {0};
  // 2 (Current) - 1 (Moved) = 1
  chrome::MoveTabsToNewWindow(browser(), indices);
  ASSERT_TRUE(browser()->tab_strip_model()->count() == 1);

  // Multi-Tab Move to New Window.
  // 1 (Current) + 3 (Added) = 4
  AddTabs(browser(), 3);
  indices = {0, 1};
  // 4 (Current) - 2 (Moved) = 2
  chrome::MoveTabsToNewWindow(browser(), indices);
  ASSERT_TRUE(browser()->tab_strip_model()->count() == 2);

  // Check that the two additional windows have been created.
  BrowserList* active_browser_list = BrowserList::GetInstance();
  EXPECT_EQ(3u, active_browser_list->size());

  // Check that the tabs made it to other windows.
  Browser* browser = active_browser_list->get(1);
  EXPECT_EQ(1, browser->tab_strip_model()->count());
  browser = active_browser_list->get(2);
  EXPECT_EQ(2, browser->tab_strip_model()->count());
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, MoveGroupToNewWindow) {
  auto AddTabs = [](Browser* browser, unsigned int num_tabs) {
    for (unsigned int i = 0; i < num_tabs; ++i) {
      chrome::NewTab(browser);
    }
  };

  AddTabs(browser(), 2);
  std::vector<int> indices = {1, 2};
  tab_groups::TabGroupId group_id =
      browser()->tab_strip_model()->AddToNewGroup(indices);
  browser()
      ->tab_strip_model()
      ->group_model()
      ->GetTabGroup(group_id)
      ->SetVisualData(tab_groups::TabGroupVisualData(
          u"Test Group", tab_groups::TabGroupColorId::kGrey));
  ui_test_utils::BrowserChangeObserver new_browser_observer(
      nullptr, ui_test_utils::BrowserChangeObserver::ChangeType::kAdded);

  chrome::MoveGroupToNewWindow(browser(), group_id);
  ASSERT_TRUE(browser()->tab_strip_model()->count() == 1);

  Browser* active_browser = new_browser_observer.Wait();
  ui_test_utils::WaitUntilBrowserBecomeActive(active_browser);

  EXPECT_TRUE(
      active_browser->tab_strip_model()->group_model()->ContainsTabGroup(
          group_id));
  EXPECT_EQ(active_browser->tab_strip_model()
                ->group_model()
                ->GetTabGroup(group_id)
                ->ListTabs()
                .length(),
            2u);
  EXPECT_EQ(*active_browser->tab_strip_model()
                 ->group_model()
                 ->GetTabGroup(group_id)
                 ->visual_data(),
            tab_groups::TabGroupVisualData(u"Test Group",
                                           tab_groups::TabGroupColorId::kGrey));
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, MoveToExistingWindow) {
  auto AddTabs = [](Browser* browser, unsigned int num_tabs) {
    for (unsigned int i = 0; i < num_tabs; ++i) {
      chrome::NewTab(browser);
    }
  };

  // Create another window, and add tabs.
  Browser* second_window =
      ui_test_utils::OpenNewEmptyWindowAndWaitUntilActivated(
          browser()->profile());
  AddTabs(browser(), 2);
  AddTabs(second_window, 1);
  ASSERT_TRUE(browser()->tab_strip_model()->count() == 3);
  ASSERT_TRUE(second_window->tab_strip_model()->count() == 2);

  // Single tab move to an existing window.
  std::vector<int> indices = {0};
  chrome::MoveTabsToExistingWindow(browser(), second_window, indices);
  ASSERT_TRUE(browser()->tab_strip_model()->count() == 2);
  ASSERT_TRUE(second_window->tab_strip_model()->count() == 3);

  // Multiple tab move to an existing window.
  indices = {0, 2};
  chrome::MoveTabsToExistingWindow(second_window, browser(), indices);
  ASSERT_TRUE(browser()->tab_strip_model()->count() == 4);
  ASSERT_TRUE(second_window->tab_strip_model()->count() == 1);
}

// Tests IDC_MOVE_TAB_TO_NEW_WINDOW. This is a browser test and not a unit test
// since it needs to create a new browser window, which doesn't work with a
// TestingProfile.
IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, MoveActiveTabToNewWindow) {
  GURL url1("chrome://version");
  GURL url2("chrome://about");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url1));

  // Should be disabled with 1 tab.
  EXPECT_FALSE(chrome::IsCommandEnabled(browser(), IDC_MOVE_TAB_TO_NEW_WINDOW));
  ASSERT_TRUE(AddTabAtIndex(1, url2, ui::PAGE_TRANSITION_LINK));
  // Two tabs is enough for it to be meaningful to pop one out.
  EXPECT_TRUE(chrome::IsCommandEnabled(browser(), IDC_MOVE_TAB_TO_NEW_WINDOW));

  BrowserList* browser_list = BrowserList::GetInstance();
  // Pre-command, assert that we have one browser, with two tabs, with the
  // url2 tab active.
  EXPECT_EQ(browser_list->size(), 1u);
  EXPECT_EQ(browser()->tab_strip_model()->count(), 2);
  EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents()->GetURL(),
            url2);

  ui_test_utils::BrowserChangeObserver new_browser_observer(
      nullptr, ui_test_utils::BrowserChangeObserver::ChangeType::kAdded);
  chrome::ExecuteCommand(browser(), IDC_MOVE_TAB_TO_NEW_WINDOW);
  Browser* active_browser = new_browser_observer.Wait();
  ui_test_utils::WaitUntilBrowserBecomeActive(active_browser);

  // Now we should have: two browsers, each with one tab (url1 in browser(),
  // and url2 in the new one).
  EXPECT_EQ(browser_list->size(), 2u);
  EXPECT_NE(active_browser, browser());
  EXPECT_EQ(browser()->tab_strip_model()->count(), 1);
  EXPECT_EQ(active_browser->tab_strip_model()->count(), 1);
  EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents()->GetURL(),
            url1);
  EXPECT_EQ(active_browser->tab_strip_model()->GetActiveWebContents()->GetURL(),
            url2);
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest,
                       MoveActiveTabToNewWindowMultipleSelection) {
  GURL url1("chrome://version");
  GURL url2("chrome://about");
  GURL url3("chrome://terms");
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), url1));
  ASSERT_TRUE(AddTabAtIndex(1, url2, ui::PAGE_TRANSITION_LINK));
  ASSERT_TRUE(AddTabAtIndex(2, url3, ui::PAGE_TRANSITION_LINK));
  // Select the first tab.
  browser()->tab_strip_model()->SelectTabAt(0);
  // First and third (since it's active) should be selected
  EXPECT_TRUE(browser()->tab_strip_model()->IsTabSelected(0));
  EXPECT_FALSE(browser()->tab_strip_model()->IsTabSelected(1));
  EXPECT_TRUE(browser()->tab_strip_model()->IsTabSelected(2));

  ui_test_utils::BrowserChangeObserver new_browser_observer(
      nullptr, ui_test_utils::BrowserChangeObserver::ChangeType::kAdded);
  chrome::ExecuteCommand(browser(), IDC_MOVE_TAB_TO_NEW_WINDOW);
  Browser* active_browser = new_browser_observer.Wait();
  ui_test_utils::WaitUntilBrowserBecomeActive(active_browser);

  // Now we should have two browsers:
  // The original, now with only a single tab: url2
  // The new one with the two tabs we moved: url1 and url3. This one should
  // be active.
  BrowserList* browser_list = BrowserList::GetInstance();
  EXPECT_EQ(browser_list->size(), 2u);
  EXPECT_NE(active_browser, browser());
  ASSERT_EQ(browser()->tab_strip_model()->count(), 1);
  ASSERT_EQ(active_browser->tab_strip_model()->count(), 2);
  EXPECT_EQ(browser()->tab_strip_model()->GetActiveWebContents()->GetURL(),
            url2);
  EXPECT_EQ(active_browser->tab_strip_model()->GetWebContentsAt(0)->GetURL(),
            url1);
  EXPECT_EQ(active_browser->tab_strip_model()->GetWebContentsAt(1)->GetURL(),
            url3);
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, StartsOrganizationRequest) {
  base::HistogramTester histogram_tester;

  chrome::ExecuteCommand(browser(), IDC_ORGANIZE_TABS);

  TabOrganizationService* service =
      TabOrganizationServiceFactory::GetForProfile(browser()->profile());
  const TabOrganizationSession* session =
      service->GetSessionForBrowser(browser());

  EXPECT_EQ(TabOrganizationRequest::State::NOT_STARTED,
            session->request()->state());

  histogram_tester.ExpectUniqueSample("Tab.Organization.AllEntrypoints.Clicked",
                                      true, 1);
  histogram_tester.ExpectUniqueSample("Tab.Organization.ThreeDotMenu.Clicked",
                                      true, 1);
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, ShowsDeclutter) {
  TabSearchBubbleHost* tab_search_bubble_host =
      BrowserView::GetBrowserViewForBrowser(browser())
          ->GetTabSearchBubbleHost();
  EXPECT_FALSE(tab_search_bubble_host->bubble_created_time_for_testing());

  chrome::ExecuteCommand(browser(), IDC_DECLUTTER_TABS);

  EXPECT_TRUE(tab_search_bubble_host->bubble_created_time_for_testing());
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest,
                       ConvertPopupToTabbedBrowserShutdownRace) {
  // Confirm we do not incorrectly start shutdown when converting a popup into a
  // tab, in the case where the popup is the only active Browser object
  Browser* popup_browser = Browser::Create(
      Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), true));
  chrome::AddTabAt(popup_browser, GURL(url::kAboutBlankURL), -1, true);
  popup_browser->tab_strip_model()->SelectTabAt(0);
  browser()->tab_strip_model()->CloseAllTabs();
  ConvertPopupToTabbedBrowser(popup_browser);
  EXPECT_EQ(false, browser_shutdown::HasShutdownStarted());
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest,
                       OpenProductSpecifications_ShowNewTab) {
  // Mock that the disclosure dialog has shown.
  browser()->profile()->GetPrefs()->SetInteger(
      commerce::kProductSpecificationsAcceptedDisclosureVersion,
      static_cast<int>(
          commerce::product_specifications::mojom::DisclosureVersion::kV1));

  int tab_count = browser()->tab_strip_model()->count();
  chrome::OpenCommerceProductSpecificationsTab(
      browser(), {GURL("foo.com"), GURL("bar.com")}, 0);

  auto* dialog = commerce::ProductSpecificationsDisclosureDialog::
      current_instance_for_testing();
  ASSERT_FALSE(dialog);
  // No new tab is created since the dialog will block creating new product
  // specifications tab.
  ASSERT_EQ(tab_count + 1, browser()->tab_strip_model()->count());
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest,
                       OpenProductSpecifications_ShowDialog) {
  int tab_count = browser()->tab_strip_model()->count();
  chrome::OpenCommerceProductSpecificationsTab(
      browser(), {GURL("foo.com"), GURL("bar.com")}, 0);

  auto* dialog = commerce::ProductSpecificationsDisclosureDialog::
      current_instance_for_testing();
  ASSERT_TRUE(dialog);
  // No new tab is created.
  ASSERT_EQ(tab_count, browser()->tab_strip_model()->count());
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, AddingToReadingListOpensToast) {
  GURL main_url(https_server_.GetURL("a.test", "/iframe.html"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
  chrome::ExecuteCommand(browser(), IDC_READING_LIST_MENU_ADD_TAB);
  EXPECT_TRUE(browser()->GetFeatures().toast_controller()->IsShowingToast());
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest,
                       AddingToReadingListWithSidePanelShowsNoToast) {
  GURL main_url(https_server_.GetURL("a.test", "/iframe.html"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
  auto* side_panel_coordinator =
      browser()->GetFeatures().side_panel_coordinator();
  side_panel_coordinator->Show(SidePanelEntryId::kReadingList);
  ASSERT_TRUE(base::test::RunUntil(
      [&]() { return side_panel_coordinator->IsSidePanelShowing(); }));
  chrome::ExecuteCommand(browser(), IDC_READING_LIST_MENU_ADD_TAB);
  EXPECT_FALSE(browser()->GetFeatures().toast_controller()->IsShowingToast());
}

IN_PROC_BROWSER_TEST_F(BrowserCommandsTest, CopyingUrlOpensToast) {
  GURL main_url(https_server_.GetURL("a.test", "/iframe.html"));
  ASSERT_TRUE(ui_test_utils::NavigateToURL(browser(), main_url));
  chrome::ExecuteCommand(browser(), IDC_COPY_URL);
  EXPECT_TRUE(browser()->GetFeatures().toast_controller()->IsShowingToast());
}

}  // namespace chrome
