// Copyright 2012 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_list.h"

#include <algorithm>

#include "base/auto_reset.h"
#include "base/check.h"
#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/user_metrics.h"
#include "base/observer_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/buildflags.h"
#include "chrome/browser/lifetime/application_lifetime_desktop.h"
#include "chrome/browser/lifetime/browser_shutdown.h"
#include "chrome/browser/lifetime/termination_notification.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/sessions/app_session_service_factory.h"
#include "chrome/browser/sessions/session_service_factory.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/browser_list_enumerator.h"
#include "chrome/browser/ui/browser_list_observer.h"
#include "chrome/browser/ui/browser_window.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface_iterator.h"
#include "components/keep_alive_registry/keep_alive_registry.h"
#include "components/keep_alive_registry/keep_alive_types.h"

using base::UserMetricsAction;
using content::WebContents;

namespace {

BrowserList::BrowserWeakVector GetBrowsersToClose(Profile* profile) {
  BrowserList::BrowserWeakVector browsers_to_close;
  for (Browser* browser : *BrowserList::GetInstance()) {
    if (browser->profile()->GetOriginalProfile() ==
        profile->GetOriginalProfile()) {
      browsers_to_close.push_back(browser->AsWeakPtr());
    }
  }
  return browsers_to_close;
}

BrowserList::BrowserWeakVector GetIncognitoBrowsersToClose(Profile* profile) {
  BrowserList::BrowserWeakVector browsers_to_close;
  for (Browser* browser : *BrowserList::GetInstance()) {
    if (browser->profile() == profile) {
      browsers_to_close.push_back(browser->AsWeakPtr());
    }
  }
  return browsers_to_close;
}

}  // namespace

// static
base::LazyInstance<base::ObserverList<BrowserListObserver>,
                   BrowserList::ObserverListTraits>
    BrowserList::observers_ = LAZY_INSTANCE_INITIALIZER;

// static
BrowserList* BrowserList::instance_ = nullptr;

////////////////////////////////////////////////////////////////////////////////
// BrowserList, public:

// static
BrowserList* BrowserList::GetInstance() {
  BrowserList** list = &instance_;
  if (!*list) {
    *list = new BrowserList;
  }
  return *list;
}

// static
void BrowserList::AddBrowser(Browser* browser) {
  DCHECK(browser);
  DCHECK(browser->window()) << "Browser should not be added to BrowserList "
                               "until it is fully constructed.";
  GetInstance()->browsers_.push_back(browser);

  browser->RegisterKeepAlive();

  AddBrowserToActiveList(browser);

  for (BrowserListObserver& observer : observers_.Get()) {
    observer.OnBrowserAdded(browser);
  }

  if (browser->profile()->IsGuestSession()) {
    base::UmaHistogramCounts100("Browser.WindowCount.Guest",
                                GetGuestBrowserCount());
  } else if (browser->profile()->IsIncognitoProfile()) {
    base::UmaHistogramCounts100(
        "Browser.WindowCount.Incognito",
        GetOffTheRecordBrowsersActiveForProfile(browser->profile()));
  }
}

// static
void BrowserList::RemoveBrowser(Browser* browser) {
  // Remove |browser| from the appropriate list instance.
  BrowserList* browser_list = GetInstance();
  RemoveBrowserFrom(browser, &browser_list->browsers_ordered_by_activation_);

  RemoveBrowserFrom(browser, &browser_list->browsers_);

  for (BrowserListObserver& observer : observers_.Get()) {
    observer.OnBrowserRemoved(browser);
  }

  browser->UnregisterKeepAlive();

  // If we're exiting, send out the APP_TERMINATING notification to allow other
  // modules to shut themselves down.
  if (!KeepAliveRegistry::GetInstance()->IsOriginRegistered(
          KeepAliveOrigin::BROWSER) &&
      (browser_shutdown::IsTryingToQuit() ||
       g_browser_process->IsShuttingDown())) {
    // Last browser has just closed, and this is a user-initiated quit or there
    // is no module keeping the app alive, so send out our notification. No need
    // to call ProfileManager::ShutdownSessionServices() as part of the
    // shutdown, because Browser::WindowClosing() already makes sure that the
    // SessionService is created and notified.
    browser_shutdown::NotifyAppTerminating();
    chrome::OnAppExiting();
  }
}

// static
void BrowserList::AddBrowserToActiveList(Browser* browser) {
  if (browser->IsActive()) {
    SetLastActive(browser);
    return;
  }

  // |BrowserList::browsers_ordered_by_activation_| should contain every
  // browser, so prepend any inactive browsers to it.
  BrowserVector* active_browsers =
      &GetInstance()->browsers_ordered_by_activation_;
  RemoveBrowserFrom(browser, active_browsers);
  active_browsers->insert(active_browsers->begin(), browser);
}

// static
void BrowserList::AddObserver(BrowserListObserver* observer) {
  observers_.Get().AddObserver(observer);
}

// static
void BrowserList::RemoveObserver(BrowserListObserver* observer) {
  observers_.Get().RemoveObserver(observer);
}

// static
void BrowserList::CloseAllBrowsersWithProfile(Profile* profile) {
  BrowserVector browsers_to_close;
  for (Browser* browser : *BrowserList::GetInstance()) {
    if (browser->profile()->GetOriginalProfile() ==
        profile->GetOriginalProfile()) {
      browsers_to_close.push_back(browser);
    }
  }

  for (const auto& it : browsers_to_close) {
    it->window()->Close();
  }
}

// static
void BrowserList::CloseAllBrowsersWithProfile(
    Profile* profile,
    const CloseCallback& on_close_success,
    const CloseCallback& on_close_aborted,
    bool skip_beforeunload) {
  SessionServiceFactory::ShutdownForProfile(profile);
  AppSessionServiceFactory::ShutdownForProfile(profile);

  TryToCloseBrowserList(GetBrowsersToClose(profile), on_close_success,
                        on_close_aborted, profile->GetPath(),
                        skip_beforeunload);
}

// static
void BrowserList::CloseAllBrowsersWithIncognitoProfile(
    Profile* profile,
    const CloseCallback& on_close_success,
    const CloseCallback& on_close_aborted,
    bool skip_beforeunload) {
  DCHECK(profile->IsOffTheRecord());
  auto browsers_to_close = GetIncognitoBrowsersToClose(profile);

  // When closing devtools browser related to incognito browser, do not skip
  // calling before unload handlers.
  skip_beforeunload =
      skip_beforeunload &&
      std::ranges::none_of(browsers_to_close, &Browser::is_type_devtools);
  TryToCloseBrowserList(browsers_to_close, on_close_success, on_close_aborted,
                        profile->GetPath(), skip_beforeunload);
}

// static
void BrowserList::TryToCloseBrowserList(
    const BrowserWeakVector& browsers_to_close,
    const CloseCallback& on_close_success,
    const CloseCallback& on_close_aborted,
    const base::FilePath& profile_path,
    const bool skip_beforeunload) {
  for (auto& weak_browser : browsers_to_close) {
    if (weak_browser &&
        weak_browser->TryToCloseWindow(
            skip_beforeunload,
            base::BindRepeating(&BrowserList::PostTryToCloseBrowserWindow,
                                browsers_to_close, on_close_success,
                                on_close_aborted, profile_path,
                                skip_beforeunload))) {
      return;
    }
  }

  if (on_close_success) {
    on_close_success.Run(profile_path);
  }

  for (auto& weak_b : browsers_to_close) {
    // BeforeUnload handlers may close browser windows, so we need to explicitly
    // check whether they still exist.
    if (weak_b && weak_b->window()) {
      weak_b->window()->Close();
    }
  }
}

// static
void BrowserList::PostTryToCloseBrowserWindow(
    const BrowserWeakVector& browsers_to_close,
    const CloseCallback& on_close_success,
    const CloseCallback& on_close_aborted,
    const base::FilePath& profile_path,
    const bool skip_beforeunload,
    bool tab_close_confirmed) {
  // We need this bool to avoid infinite recursion when resetting the
  // BeforeUnload handlers, since doing that will trigger calls back to this
  // method for each affected window.
  static bool resetting_handlers = false;

  if (tab_close_confirmed) {
    TryToCloseBrowserList(browsers_to_close, on_close_success, on_close_aborted,
                          profile_path, skip_beforeunload);
  } else if (!resetting_handlers) {
    base::AutoReset<bool> resetting_handlers_scoper(&resetting_handlers, true);
    for (auto& weak_browser : browsers_to_close) {
      // This function is called asynchronously, so that the Browser may have
      // been destroyed by the time we get here.
      if (weak_browser) {
        weak_browser->ResetTryToCloseWindow();
      }
    }
    if (on_close_aborted) {
      on_close_aborted.Run(profile_path);
    }
  }
}

// static
void BrowserList::MoveBrowsersInWorkspaceToFront(
    const std::string& new_workspace) {
  DCHECK(!new_workspace.empty());

  BrowserList* instance = GetInstance();

  BrowserWindowInterface* const old_last_active =
      GetLastActiveBrowserWindowInterfaceWithAnyProfile();
  BrowserVector& last_active_browsers =
      instance->browsers_ordered_by_activation_;

  // Perform a stable partition on the browsers in the list so that the browsers
  // in the new workspace appear after the browsers in the other workspaces.
  //
  // For example, if we have a list of browser-workspace pairs
  // [{b1, 0}, {b2, 1}, {b3, 0}, {b4, 1}]
  // and we switch to workspace 1, we want the resulting browser list to look
  // like [{b1, 0}, {b3, 0}, {b2, 1}, {b4, 1}].
  std::stable_partition(
      last_active_browsers.begin(), last_active_browsers.end(),
      [&new_workspace](Browser* browser) {
        return !browser->window()->IsVisibleOnAllWorkspaces() &&
               browser->window()->GetWorkspace() != new_workspace;
      });

  BrowserWindowInterface* const new_last_active =
      GetLastActiveBrowserWindowInterfaceWithAnyProfile();
  if (old_last_active != new_last_active) {
    for (BrowserListObserver& observer : observers_.Get()) {
      observer.OnBrowserSetLastActive(
          new_last_active ? new_last_active->GetBrowserForMigrationOnly()
                          : nullptr);
    }
  }
}

// static
void BrowserList::SetLastActive(Browser* browser) {
  BrowserList* instance = GetInstance();
  DCHECK(base::Contains(*instance, browser))
      << "SetLastActive called for a browser before the browser was added to "
         "the BrowserList.";
  DCHECK(browser->window())
      << "SetLastActive called for a browser with no window set.";

  base::RecordAction(UserMetricsAction("ActiveBrowserChanged"));

  RemoveBrowserFrom(browser, &instance->browsers_ordered_by_activation_);
  instance->browsers_ordered_by_activation_.push_back(browser);

  for (BrowserListObserver& observer : observers_.Get()) {
    observer.OnBrowserSetLastActive(browser);
  }
}

// static
void BrowserList::NotifyBrowserNoLongerActive(Browser* browser) {
  BrowserList* instance = GetInstance();
  DCHECK(base::Contains(*instance, browser))
      << "NotifyBrowserNoLongerActive called for a browser before the browser "
         "was added to the BrowserList.";
  DCHECK(browser->window())
      << "NotifyBrowserNoLongerActive called for a browser with no window set.";

  for (BrowserListObserver& observer : observers_.Get()) {
    observer.OnBrowserNoLongerActive(browser);
  }
}

// static
bool BrowserList::IsOffTheRecordBrowserActive() {
  for (Browser* browser : *BrowserList::GetInstance()) {
    if (browser->profile()->IsOffTheRecord()) {
      return true;
    }
  }
  return false;
}

// static
int BrowserList::GetOffTheRecordBrowsersActiveForProfile(Profile* profile) {
  BrowserList* list = BrowserList::GetInstance();
  return std::ranges::count_if(*list, [profile](Browser* browser) {
    return browser->profile()->IsSameOrParent(profile) &&
           browser->profile()->IsOffTheRecord() && !browser->is_type_devtools();
  });
}

// static
size_t BrowserList::GetIncognitoBrowserCount() {
  BrowserList* list = BrowserList::GetInstance();
  return std::ranges::count_if(*list, [](Browser* browser) {
    return browser->profile()->IsIncognitoProfile() &&
           !browser->is_type_devtools();
  });
}

// static
size_t BrowserList::GetGuestBrowserCount() {
  BrowserList* list = BrowserList::GetInstance();
  return std::ranges::count_if(*list, [](Browser* browser) {
    return browser->profile()->IsGuestSession() && !browser->is_type_devtools();
  });
}

// static
bool BrowserList::IsOffTheRecordBrowserInUse(Profile* profile) {
  BrowserList* list = BrowserList::GetInstance();
  return std::ranges::any_of(*list, [profile](Browser* browser) {
    return browser->profile()->IsSameOrParent(profile) &&
           browser->profile()->IsOffTheRecord();
  });
}

////////////////////////////////////////////////////////////////////////////////
// BrowserList, private:

BrowserList::BrowserList() = default;

BrowserList::~BrowserList() = default;

// static
void BrowserList::RemoveBrowserFrom(Browser* browser,
                                    BrowserVector* browser_list) {
  auto remove_browser = std::ranges::find(*browser_list, browser);
  if (remove_browser != browser_list->end()) {
    browser_list->erase(remove_browser);
  }
}
