// Copyright 2015 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/check_op.h"
#include "base/macros.h"
#include "base/strings/stringprintf.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/download/chrome_download_manager_delegate.h"
#include "chrome/browser/download/download_core_service.h"
#include "chrome/browser/download/download_core_service_factory.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/test/base/test_browser_window.h"
#include "chrome/test/base/testing_browser_process.h"
#include "chrome/test/base/testing_profile.h"
#include "chrome/test/base/testing_profile_manager.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/browser_context.h"
#include "content/public/test/browser_task_environment.h"
#include "extensions/buildflags/buildflags.h"
#include "testing/gtest/include/gtest/gtest.h"

class TestingDownloadCoreService : public DownloadCoreService {
 public:
  TestingDownloadCoreService() : download_count_(0) {}
  ~TestingDownloadCoreService() override {}

  // All methods that aren't expected to be called in the execution of
  // this unit test are marked to result in test failure.  Using a simple
  // mock for this class should be re-evaluated if any of these
  // methods are being called; it may mean that a more fully featured
  // DownloadCoreService implementation is needed.

  void SetDownloadCount(int download_count) {
    download_count_ = download_count;
  }

  // DownloadCoreService
  ChromeDownloadManagerDelegate* GetDownloadManagerDelegate() override {
    ADD_FAILURE();
    return nullptr;
  }

  DownloadHistory* GetDownloadHistory() override {
    ADD_FAILURE();
    return nullptr;
  }

#if BUILDFLAG(ENABLE_EXTENSIONS)
  extensions::ExtensionDownloadsEventRouter* GetExtensionEventRouter()
      override {
    ADD_FAILURE();
    return nullptr;
  }
#endif
  bool HasCreatedDownloadManager() override { return true; }

  int NonMaliciousDownloadCount() const override { return download_count_; }

  void CancelDownloads() override {}

  void SetDownloadManagerDelegateForTesting(
      std::unique_ptr<ChromeDownloadManagerDelegate> delegate) override {
    ADD_FAILURE();
  }

  bool IsShelfEnabled() override { return true; }

  // KeyedService
  void Shutdown() override {}

 private:
  int download_count_;

  DISALLOW_COPY_AND_ASSIGN(TestingDownloadCoreService);
};

static std::unique_ptr<KeyedService> CreateTestingDownloadCoreService(
    content::BrowserContext* browser_context) {
  return std::unique_ptr<KeyedService>(new TestingDownloadCoreService());
}

class BrowserCloseTest : public testing::Test {
 public:
  BrowserCloseTest()
      : profile_manager_(TestingBrowserProcess::GetGlobal()), name_index_(0) {}

  ~BrowserCloseTest() override {}

  void SetUp() override { ASSERT_TRUE(profile_manager_.SetUp()); }

  void TearDown() override {
    for (auto& browser_window_pair : browser_windows_) {
      while (!browser_window_pair.second.empty()) {
        TestBrowserWindow* window = browser_window_pair.second.back();
        browser_window_pair.second.pop_back();
        delete window;
      }
    }
    for (auto& browser_pair : browsers_) {
      while (!browser_pair.second.empty()) {
        Browser* browser = browser_pair.second.back();
        browser_pair.second.pop_back();
        delete browser;
      }
    }
  }

  // Create a profile with the specified number of windows and downloads
  // associated with it.
  Profile* CreateProfile(int windows, int downloads) {
    std::string name(base::StringPrintf("Profile_%d", ++name_index_));
    TestingProfile* profile = profile_manager_.CreateTestingProfile(name);

    ConfigureCreatedProfile(profile, windows, downloads);

    return profile;
  }

  Profile* CreateIncognitoProfile(Profile* profile,
                                  int windows,
                                  int downloads) {
    Profile* otr_profile =
        profile->GetPrimaryOTRProfile(/*create_if_needed=*/true);

    ConfigureCreatedProfile(otr_profile, windows, downloads);

    return otr_profile;
  }

  Browser* GetProfileBrowser(Profile* profile, int index) {
    CHECK(browsers_.end() != browsers_.find(profile));
    CHECK_GT(browsers_[profile].size(), static_cast<size_t>(index));

    return browsers_[profile][index];
  }

  TestingProfileManager* profile_manager() { return &profile_manager_; }

 protected:
  void ConfigureCreatedProfile(Profile* profile,
                               int num_windows,
                               int num_downloads) {
    DownloadCoreServiceFactory::GetInstance()->SetTestingFactory(
        profile, base::BindRepeating(&CreateTestingDownloadCoreService));
    DownloadCoreService* download_core_service(
        DownloadCoreServiceFactory::GetForBrowserContext(profile));
    TestingDownloadCoreService* mock_download_service(
        static_cast<TestingDownloadCoreService*>(download_core_service));
    mock_download_service->SetDownloadCount(num_downloads);

    CHECK(browser_windows_.end() == browser_windows_.find(profile));
    CHECK(browsers_.end() == browsers_.find(profile));

    std::vector<TestBrowserWindow*> windows;
    std::vector<Browser*> browsers;
    for (int i = 0; i < num_windows; ++i) {
      TestBrowserWindow* window = new TestBrowserWindow();
      Browser::CreateParams params(profile, true);
      params.type = Browser::TYPE_NORMAL;
      params.window = window;
      Browser* browser = Browser::Create(params);

      windows.push_back(window);
      browsers.push_back(browser);
    }

    browser_windows_[profile] = windows;
    browsers_[profile] = browsers;
  }

 private:
  // Note that the vector elements are all owned by this class and must be
  // cleaned up.
  std::map<Profile*, std::vector<TestBrowserWindow*>> browser_windows_;
  std::map<Profile*, std::vector<Browser*>> browsers_;

  content::BrowserTaskEnvironment task_environment_;
  TestingProfileManager profile_manager_;
  int name_index_;
};

// Last window close (incognito window) will trigger warning.
TEST_F(BrowserCloseTest, LastWindowIncognito) {
  Profile* profile = CreateProfile(0, 0);
  Profile* incognito_profile = CreateIncognitoProfile(profile, 1, 1);
  Browser* browser = GetProfileBrowser(incognito_profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kBrowserShutdown,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
  EXPECT_EQ(num_downloads_blocking, 1);
}

// Last incognito window close triggers incognito warning.
TEST_F(BrowserCloseTest, LastIncognito) {
  Profile* profile = CreateProfile(1, 0);
  Profile* incognito_profile = CreateIncognitoProfile(profile, 1, 1);
  Browser* browser(GetProfileBrowser(incognito_profile, 0));

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kLastWindowInIncognitoProfile,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
  EXPECT_EQ(num_downloads_blocking, 1);

  EXPECT_EQ(false, browser->CanCloseWithInProgressDownloads());
}

// Last incognito window close with no downloads => no warning.
TEST_F(BrowserCloseTest, LastIncognitoNoDownloads) {
  Profile* profile = CreateProfile(0, 0);
  Profile* incognito_profile = CreateIncognitoProfile(profile, 1, 0);
  Browser* browser = GetProfileBrowser(incognito_profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kOk,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
}

// Last incognito window with window+download on another incognito profile
// => no warning.
TEST_F(BrowserCloseTest, NoIncognitoCrossChat) {
  Profile* profile1 = CreateProfile(0, 0);
  Profile* incognito_profile1 = CreateIncognitoProfile(profile1, 1, 0);
  Profile* profile2 = CreateProfile(0, 0);
  CreateIncognitoProfile(profile2, 1, 1);

  Browser* browser = GetProfileBrowser(incognito_profile1, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kOk,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
}

// Non-last incognito window => no warning.
TEST_F(BrowserCloseTest, NonLastIncognito) {
  Profile* profile = CreateProfile(0, 0);
  Profile* incognito_profile = CreateIncognitoProfile(profile, 2, 1);
  Browser* browser = GetProfileBrowser(incognito_profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kOk,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
}

// Non-last regular window => no warning.
TEST_F(BrowserCloseTest, NonLastRegular) {
  Profile* profile = CreateProfile(2, 1);
  Browser* browser = GetProfileBrowser(profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kOk,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
}

// Last regular window triggers browser close warning.
TEST_F(BrowserCloseTest, LastRegular) {
  Profile* profile = CreateProfile(1, 1);
  Browser* browser = GetProfileBrowser(profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kBrowserShutdown,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
  EXPECT_EQ(num_downloads_blocking, 1);
#if defined(OS_MAC) || BUILDFLAG(IS_CHROMEOS_ASH)
  EXPECT_EQ(true, browser->CanCloseWithInProgressDownloads());
#else
  EXPECT_EQ(false, browser->CanCloseWithInProgressDownloads());
#endif
}

// Last regular window triggers browser close warning if download is on a
// different profile.
TEST_F(BrowserCloseTest, LastRegularDifferentProfile) {
  Profile* profile1 = CreateProfile(1, 0);
  CreateProfile(0, 1);

  Browser* browser = GetProfileBrowser(profile1, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kBrowserShutdown,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
  EXPECT_EQ(num_downloads_blocking, 1);
}

// Last regular + incognito window + download => no warning.
TEST_F(BrowserCloseTest, LastRegularPlusIncognito) {
  Profile* profile = CreateProfile(1, 0);
  CreateIncognitoProfile(profile, 1, 1);

  Browser* browser = GetProfileBrowser(profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kOk,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
}

// Last regular window + window on other profile => no warning.
TEST_F(BrowserCloseTest, LastRegularPlusOtherProfile) {
  Profile* profile = CreateProfile(1, 1);
  CreateProfile(1, 0);

  Browser* browser = GetProfileBrowser(profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kOk,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
}

// Last regular window + window on other incognito profile => no warning.
TEST_F(BrowserCloseTest, LastRegularPlusOtherIncognito) {
  Profile* profile1 = CreateProfile(1, 0);
  Profile* profile2 = CreateProfile(0, 0);
  CreateIncognitoProfile(profile2, 1, 1);

  Browser* browser = GetProfileBrowser(profile1, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kOk,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
}

// Last regular + download + incognito window => no warning.
TEST_F(BrowserCloseTest, LastRegularPlusIncognito2) {
  Profile* profile = CreateProfile(1, 1);
  CreateIncognitoProfile(profile, 1, 0);

  Browser* browser = GetProfileBrowser(profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kOk,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
}

// Multiple downloads are recognized.
TEST_F(BrowserCloseTest, Plural) {
  Profile* profile = CreateProfile(1, 2);

  Browser* browser = GetProfileBrowser(profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kBrowserShutdown,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
  EXPECT_EQ(2, num_downloads_blocking);
}

// Multiple downloads are recognized for incognito.
TEST_F(BrowserCloseTest, PluralIncognito) {
  Profile* profile = CreateProfile(1, 0);
  Profile* incognito_profile = CreateIncognitoProfile(profile, 1, 2);

  Browser* browser = GetProfileBrowser(incognito_profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kLastWindowInIncognitoProfile,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
  EXPECT_EQ(2, num_downloads_blocking);
}

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

  Profile* CreateGuestProfile(int windows, int downloads) {
    TestingProfile* profile = profile_manager()->CreateGuestProfile();
    Profile* guest_profile =
        is_ephemeral_
            ? profile
            : profile->GetPrimaryOTRProfile(/*create_if_needed=*/true);
    ConfigureCreatedProfile(guest_profile, windows, downloads);

    return guest_profile;
  }

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

// Last window close (guest window) will trigger warning.
TEST_P(GuestBrowserCloseTest, LastWindowGuest) {
  Profile* guest_profile = CreateGuestProfile(1, 1);
  Browser* browser = GetProfileBrowser(guest_profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kBrowserShutdown,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
  EXPECT_EQ(num_downloads_blocking, 1);
}

// Last guest window close triggers download warning.
TEST_P(GuestBrowserCloseTest, LastGuest) {
  CreateProfile(1, 0);
  Profile* profile = CreateGuestProfile(1, 1);
  Browser* browser(GetProfileBrowser(profile, 0));

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kLastWindowInGuestSession,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
  EXPECT_EQ(num_downloads_blocking, 1);

  EXPECT_EQ(false, browser->CanCloseWithInProgressDownloads());
}

// Last guest window close with no downloads => no warning.
TEST_P(GuestBrowserCloseTest, LastGuestNoDownloads) {
  Profile* profile = CreateGuestProfile(1, 0);
  Browser* browser = GetProfileBrowser(profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kOk,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
}

// Non-last guest window => no warning.
TEST_P(GuestBrowserCloseTest, NonLastGuest) {
  Profile* profile = CreateGuestProfile(2, 1);
  Browser* browser = GetProfileBrowser(profile, 0);

  int num_downloads_blocking = 0;
  EXPECT_EQ(Browser::DownloadCloseType::kOk,
            browser->OkToCloseWithInProgressDownloads(&num_downloads_blocking));
}

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