// 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/devtools/devtools_browser_context_manager.h"

#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/no_destructor.h"
#include "base/task/single_thread_task_runner.h"
#include "chrome/browser/profiles/profile_destroyer.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.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 "chrome/browser/ui/browser_window/public/global_browser_collection.h"

namespace {

const int64_t kDestroyProfileTimeoutSeconds = 60;

void DestroyOTRProfileWhenAppropriate(base::WeakPtr<Profile> weak_profile) {
  if (Profile* profile = weak_profile.get()) {
    ProfileDestroyer::DestroyOTRProfileWhenAppropriateWithTimeout(
        profile, base::Seconds(kDestroyProfileTimeoutSeconds));
  }
}

}  // namespace

DevToolsBrowserContextManager::DevToolsBrowserContextManager() = default;

DevToolsBrowserContextManager::~DevToolsBrowserContextManager() = default;

// static
DevToolsBrowserContextManager& DevToolsBrowserContextManager::GetInstance() {
  static base::NoDestructor<DevToolsBrowserContextManager> instance;
  return *instance;
}

Profile* DevToolsBrowserContextManager::GetProfileById(
    const std::string& context_id) {
  Profile* default_profile =
      ProfileManager::GetLastUsedProfile()->GetOriginalProfile();
  if (context_id == default_profile->UniqueId()) {
    return default_profile;
  }
  auto it = otr_profiles_.find(context_id);
  if (it == otr_profiles_.end())
    return nullptr;
  return it->second;
}

content::BrowserContext* DevToolsBrowserContextManager::CreateBrowserContext() {
  Profile* original_profile =
      ProfileManager::GetLastUsedProfile()->GetOriginalProfile();

  Profile* otr_profile = original_profile->GetOffTheRecordProfile(
      Profile::OTRProfileID::CreateUniqueForDevTools(),
      /*create_if_needed=*/true);
  const std::string& context_id = otr_profile->UniqueId();

  // The two lines are matched in `StopObservingProfileIfAny()`.
  profile_observation_.AddObservation(otr_profile);
  otr_profiles_[context_id] = otr_profile;
  return otr_profile;
}

std::vector<content::BrowserContext*>
DevToolsBrowserContextManager::GetBrowserContexts() {
  std::vector<content::BrowserContext*> result;
  for (const auto& profile_pair : otr_profiles_)
    result.push_back(profile_pair.second);
  return result;
}

content::BrowserContext*
DevToolsBrowserContextManager::GetDefaultBrowserContext() {
  // Do not force profile loading (or it will blow up if called on shutdown).
  auto* last_profile = ProfileManager::GetLastUsedProfileIfLoaded();
  return last_profile ? last_profile->GetOriginalProfile() : nullptr;
}

void DevToolsBrowserContextManager::DisposeBrowserContext(
    content::BrowserContext* context,
    content::DevToolsManagerDelegate::DisposeCallback callback) {
  std::string context_id = context->UniqueId();
  if (pending_context_disposals_.find(context_id) !=
      pending_context_disposals_.end()) {
    std::move(callback).Run(false, "Disposal of browser context " + context_id +
                                       " is already pending");
    return;
  }
  auto it = otr_profiles_.find(context_id);
  if (it == otr_profiles_.end()) {
    std::move(callback).Run(
        false, "Failed to find browser context with id " + context_id);
    return;
  }

  Profile* profile = it->second;
  bool has_opened_browser = false;
  ForEachCurrentBrowserWindowInterfaceOrderedByActivation(
      [profile,
       &has_opened_browser](BrowserWindowInterface* browser_window_interface) {
        if (browser_window_interface->GetProfile() == profile) {
          has_opened_browser = true;
          return false;
        }
        return true;
      });

  // If no browsers are opened - dispose right away.
  if (!has_opened_browser) {
    StopObservingProfileIfAny(profile);
    DestroyOTRProfileWhenAppropriate(profile->GetWeakPtr());
    std::move(callback).Run(true, "");
    return;
  }

  if (pending_context_disposals_.empty()) {
    browser_collection_observation_.Observe(
        GlobalBrowserCollection::GetInstance());
  }

  pending_context_disposals_[context_id] = std::move(callback);
  chrome::CloseAllBrowsersWithIncognitoProfile(profile);
}

void DevToolsBrowserContextManager::OnProfileWillBeDestroyed(Profile* profile) {
  // This is likely happening during shutdown. We'll immediately
  // close all browser windows for our profile without unload handling.
  ForEachCurrentBrowserWindowInterfaceOrderedByActivation(
      [profile](BrowserWindowInterface* browser_window_interface) {
        if (browser_window_interface->GetProfile() == profile) {
          browser_window_interface->GetWindow()->Close();
        }
        return true;
      });

  StopObservingProfileIfAny(profile);
}

void DevToolsBrowserContextManager::OnBrowserClosed(
    BrowserWindowInterface* browser) {
  std::string context_id = browser->GetProfile()->UniqueId();
  auto pending_disposal = pending_context_disposals_.find(context_id);
  if (pending_disposal == pending_context_disposals_.end())
    return;
  bool found = false;
  ForEachCurrentBrowserWindowInterfaceOrderedByActivation(
      [browser, &found](BrowserWindowInterface* browser_window_interface) {
        if (browser_window_interface->GetProfile() == browser->GetProfile()) {
          found = true;
          return false;
        }
        return true;
      });
  if (found) {
    return;
  }

  StopObservingProfileIfAny(browser->GetProfile());

  // We cannot delete immediately here: the profile might still be referenced
  // during the browser tear-down process.
  base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
      FROM_HERE, base::BindOnce(&DestroyOTRProfileWhenAppropriate,
                                browser->GetProfile()->GetWeakPtr()));

  std::move(pending_disposal->second).Run(true, "");
  pending_context_disposals_.erase(pending_disposal);
  if (pending_context_disposals_.empty()) {
    browser_collection_observation_.Reset();
  }
}

void DevToolsBrowserContextManager::StopObservingProfileIfAny(
    Profile* profile) {
  if (!profile_observation_.IsObservingSource(profile))
    return;

  profile_observation_.RemoveObservation(profile);
  otr_profiles_.erase(profile->UniqueId());
}
