// Copyright 2014 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/chrome_devtools_manager_delegate.h"

#include <memory>
#include <utility>

#include "base/command_line.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "base/strings/strcat.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "build/build_config.h"
#include "chrome/browser/devtools/chrome_devtools_session.h"
#include "chrome/browser/devtools/device/android_device_manager.h"
#include "chrome/browser/devtools/device/tcp_device_provider.h"
#include "chrome/browser/devtools/devtools_availability_checker.h"
#include "chrome/browser/devtools/devtools_browser_context_manager.h"
#include "chrome/browser/devtools/devtools_connection_dialog.h"
#include "chrome/browser/devtools/devtools_remote_server_infobar_delegate.h"
#include "chrome/browser/devtools/devtools_window.h"
#include "chrome/browser/devtools/protocol/target_handler.h"
#include "chrome/browser/extensions/extension_tab_util.h"
#include "chrome/browser/lifetime/application_lifetime.h"
#include "chrome/browser/policy/developer_tools_policy_handler.h"
#include "chrome/browser/policy/profile_policy_connector.h"
#include "chrome/browser/profiles/keep_alive/profile_keep_alive_types.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser_window/public/browser_window_interface.h"
#include "chrome/browser/ui/browser_window/public/profile_browser_collection.h"
#include "chrome/browser/ui/navigator/browser_navigator.h"
#include "chrome/browser/ui/navigator/browser_navigator_params.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/browser/ui/webui_browser/webui_browser.h"
#include "chrome/browser/web_applications/proto/web_app_install_state.pb.h"
#include "chrome/browser/web_applications/web_app.h"
#include "chrome/browser/web_applications/web_app_filter.h"
#include "chrome/browser/web_applications/web_app_provider.h"
#include "chrome/browser/web_applications/web_app_registrar.h"
#include "chrome/browser/web_applications/web_app_tab_helper.h"
#include "chrome/browser/web_applications/web_app_utils.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/grit/browser_resources.h"
#include "components/guest_view/browser/guest_view_base.h"
#include "components/keep_alive_registry/keep_alive_types.h"
#include "components/keep_alive_registry/scoped_keep_alive.h"
#include "components/tab_groups/tab_group_id.h"
#include "components/tabs/public/tab_interface.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/devtools_agent_host_client_channel.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_switches.h"
#include "extensions/browser/extension_host.h"
#include "extensions/browser/extension_registry.h"
#include "extensions/browser/process_manager.h"
#include "extensions/browser/view_type_utils.h"
#include "extensions/common/manifest.h"
#include "extensions/common/mojom/view_type.mojom.h"
#include "ui/base/page_transition_types.h"
#include "ui/base/resource/resource_bundle.h"
#include "ui/base/window_open_disposition.h"
#include "ui/gfx/switches.h"
#include "ui/views/controls/webview/webview.h"

#if BUILDFLAG(IS_CHROMEOS)
#include "ash/constants/ash_switches.h"
#include "chromeos/constants/chromeos_features.h"
#endif

static_assert(!BUILDFLAG(IS_ANDROID),
              "This file should not be included in Android build");

using content::DevToolsAgentHost;

const char ChromeDevToolsManagerDelegate::kTypeApp[] = "app";
const char ChromeDevToolsManagerDelegate::kTypeBackgroundPage[] =
    "background_page";
const char ChromeDevToolsManagerDelegate::kTypePage[] = "page";

namespace {

// LINT.IfChange(DevToolsRemoteDebuggingConnectionPermission)
// This enum is used for UMA histograms and should not be renumbered.
enum class DevToolsRemoteDebuggingConnectionPermission {
  kAllowed = 0,
  kDenied = 1,
  kMaxValue = kDenied,
};
// LINT.ThenChange(//tools/metrics/histograms/metadata/dev/enums.xml:DevToolsRemoteDebuggingConnectionPermission)

std::optional<std::string> GetIsolatedWebAppNameAndVersion(
    content::WebContents* web_contents) {
  const webapps::AppId* app_id =
      web_app::WebAppTabHelper::GetAppId(web_contents);
  if (!app_id) {
    return std::nullopt;
  }
  const web_app::WebAppProvider* provider =
      web_app::WebAppProvider::GetForWebContents(web_contents);
  if (!provider) {
    return std::nullopt;
  }
  if (const web_app::WebApp* iwa = provider->registrar_unsafe().GetAppById(
          *app_id, web_app::WebAppFilter::IsIsolatedApp())) {
    // Version is a key part of IWA so should be displayed in inspect tool
    return base::StrCat({provider->registrar_unsafe().GetAppShortName(*app_id),
                         " (", iwa->isolation_data()->version().GetString(),
                         ")"});
  }

  return std::nullopt;
}

bool IsIsolatedWebApp(content::WebContents* web_contents) {
  return GetIsolatedWebAppNameAndVersion(web_contents).has_value();
}

bool GetExtensionInfo(content::WebContents* wc,
                      std::string* name,
                      std::string* type) {
  auto* process_manager =
      extensions::ProcessManager::Get(wc->GetBrowserContext());
  if (!process_manager) {
    return false;
  }
  const extensions::Extension* extension =
      process_manager->GetExtensionForWebContents(wc);
  if (!extension)
    return false;
  extensions::ExtensionHost* extension_host =
      process_manager->GetBackgroundHostForExtension(extension->id());
  if (extension_host && extension_host->host_contents() == wc) {
    *name = extension->name();
    *type = ChromeDevToolsManagerDelegate::kTypeBackgroundPage;
    return true;
  }
  if (extension->is_hosted_app() || extension->is_legacy_packaged_app() ||
      extension->is_platform_app()) {
    *name = extension->name();
    *type = ChromeDevToolsManagerDelegate::kTypeApp;
    return true;
  }

  auto view_type = extensions::GetViewType(wc);
  if (view_type == extensions::mojom::ViewType::kExtensionPopup ||
      view_type == extensions::mojom::ViewType::kExtensionSidePanel) {
    // Note that we are intentionally not setting name here, so that we can
    // construct a name based on the URL or page title in
    // RenderFrameDevToolsAgentHost::GetTitle()
    *type = ChromeDevToolsManagerDelegate::kTypePage;
    return true;
  }

  if (view_type == extensions::mojom::ViewType::kOffscreenDocument) {
    // Note that we are intentionally not setting name here, so that we can
    // construct a name based on the URL or page title in
    // RenderFrameDevToolsAgentHost::GetTitle()
    //
    // Use `kTypeBackgroundPage` for offscreen doc until devtools frontend is
    // updated to support a new `offscreen_document` target type. Otherwise,
    // DOM is not inspectable.
    *type = ChromeDevToolsManagerDelegate::kTypeBackgroundPage;
    return true;
  }

  // Set type to other for extensions if not matched previously.
  *type = DevToolsAgentHost::kTypeOther;
  return true;
}

ChromeDevToolsManagerDelegate* g_instance;

}  // namespace

// static
ChromeDevToolsManagerDelegate* ChromeDevToolsManagerDelegate::GetInstance() {
  return g_instance;
}

ChromeDevToolsManagerDelegate::ChromeDevToolsManagerDelegate() {
  DCHECK(!g_instance);
  g_instance = this;

#if !BUILDFLAG(IS_CHROMEOS)
  // Only create and hold keep alive for automation test for non ChromeOS.
  // ChromeOS automation test (aka tast) manages chrome instance via session
  // manager daemon. The extra keep alive is not needed and makes ChromeOS
  // not able to shutdown chrome properly. See https://crbug.com/40167603.
  base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
  if ((command_line->HasSwitch(switches::kNoStartupWindow) ||
       command_line->HasSwitch(switches::kHeadless)) &&
      (command_line->HasSwitch(switches::kRemoteDebuggingPipe) ||
       command_line->HasSwitch(switches::kRemoteDebuggingPort))) {
    // If running without a startup window with remote debugging,
    // we are controlled entirely by the automation process.
    // Keep the application running until explicit close through DevTools
    // protocol.
    keep_alive_ = std::make_unique<ScopedKeepAlive>(
        KeepAliveOrigin::REMOTE_DEBUGGING, KeepAliveRestartOption::DISABLED);

    // Also keep the initial profile alive so that TargetHandler::CreateTarget()
    // can retrieve it without risking disk access even when all pages are
    // closed. Keep-a-living the very first loaded profile looks like a
    // reasonable option.
    if (Profile* profile = ProfileManager::GetLastUsedProfile()) {
      if (profile->IsOffTheRecord()) {
        profile = profile->GetOriginalProfile();
      }
      profile_keep_alive_ = std::make_unique<ScopedProfileKeepAlive>(
          profile, ProfileKeepAliveOrigin::kRemoteDebugging);
    }
  }
#endif  // !BUILDFLAG(IS_CHROMEOS)
}

ChromeDevToolsManagerDelegate::~ChromeDevToolsManagerDelegate() {
  DCHECK(g_instance == this);
  g_instance = nullptr;
  if (infobar_) {
    infobar_->Close();
  }
}

void ChromeDevToolsManagerDelegate::Inspect(
    content::DevToolsAgentHost* agent_host) {
  DevToolsWindow::OpenDevToolsWindow(agent_host, nullptr,
                                     DevToolsOpenedByAction::kInspectLink);
}

scoped_refptr<content::DevToolsAgentHost>
ChromeDevToolsManagerDelegate::GetDevToolsAgentHost(
    content::DevToolsAgentHost* agent_host) {
  scoped_refptr<content::DevToolsAgentHost> tab_agent_host(
      content::DevToolsAgentHost::GetForTab(agent_host->GetWebContents()));
  DevToolsWindow* window =
      DevToolsWindow::FindDevToolsWindow(tab_agent_host.get());
  if (!window) {
    return nullptr;
  }
  return DevToolsAgentHost::GetOrCreateFor(window->GetDevToolsWebContents());
}

scoped_refptr<content::DevToolsAgentHost>
ChromeDevToolsManagerDelegate::OpenDevTools(
    content::DevToolsAgentHost* agent_host,
    const content::DevToolsManagerDelegate::DevToolsOptions& devtools_options) {
  scoped_refptr<content::DevToolsAgentHost> tab_agent_host(
      content::DevToolsAgentHost::GetOrCreateForTab(
          agent_host->GetWebContents()));
  DevToolsWindow::OpenDevToolsWindow(tab_agent_host, nullptr,
                                     DevToolsOpenedByAction::kUnknown,
                                     devtools_options);
  DevToolsWindow* window =
      DevToolsWindow::FindDevToolsWindow(tab_agent_host.get());
  if (!window) {
    return nullptr;
  }

  return DevToolsAgentHost::GetOrCreateFor(window->GetDevToolsWebContents());
}

void ChromeDevToolsManagerDelegate::Activate(
    content::DevToolsAgentHost* agent_host) {
  auto* web_contents = agent_host->GetWebContents();
  if (!web_contents) {
    return;
  }

  // Brings the tab to foreground. We need to do this in case the devtools
  // window is undocked and this is being called from another tab that is in
  // the foreground.
  web_contents->GetDelegate()->ActivateContents(web_contents);

  // Brings a undocked devtools window to the foreground.
  DevToolsWindow* devtools_window =
      DevToolsWindow::GetInstanceForInspectedWebContents(
          agent_host->GetWebContents());
  if (!devtools_window) {
    return;
  }
  devtools_window->ActivateWindow();
}

void ChromeDevToolsManagerDelegate::HandleCommand(
    content::DevToolsAgentHostClientChannel* channel,
    base::span<const uint8_t> message,
    NotHandledCallback callback) {
  auto it = sessions_.find(channel);
  if (it == sessions_.end()) {
    std::move(callback).Run(message);
    // This should not happen, but happens. NOTREACHED tries to get
    // a repro in some test.
    NOTREACHED();
  }
  it->second->HandleCommand(message, std::move(callback));
}

std::string ChromeDevToolsManagerDelegate::GetTargetType(
    content::WebContents* web_contents) {
  if (webui_browser::IsBrowserUIWebContents(web_contents)) {
    return DevToolsAgentHost::kTypeBrowserUI;
  }

  if (IsIsolatedWebApp(web_contents)) {
    return ChromeDevToolsManagerDelegate::kTypeApp;
  }

  if (tabs::TabInterface::MaybeGetFromContents(web_contents)) {
    return DevToolsAgentHost::kTypePage;
  }

  std::string extension_name;
  std::string extension_type;
  if (GetExtensionInfo(web_contents, &extension_name, &extension_type)) {
    return extension_type;
  }

  if (views::WebView::IsWebViewContents(web_contents)) {
    return DevToolsAgentHost::kTypePage;
  }

  return DevToolsAgentHost::kTypeOther;
}

std::optional<bool> ChromeDevToolsManagerDelegate::ShouldReportAsTabTarget(
    content::WebContents* web_contents) {
  if (webui_browser::IsBrowserUIWebContents(web_contents)) {
    // Return false for browser UI so its WebContents is not reported as Tab.
    // Browser UI is not a Tab and can not be interacted as a Tab. Reporting
    // browser UI WebContents as Tab target will confuse tools such as test
    // drivers and cause them to fail.
    return false;
  }

  if (tabs::TabInterface::MaybeGetFromContents(web_contents)) {
    return true;
  }

  return std::nullopt;
}

std::string ChromeDevToolsManagerDelegate::GetTargetTitle(
    content::WebContents* web_contents) {
  if (auto iwa_name_version = GetIsolatedWebAppNameAndVersion(web_contents)) {
    return *iwa_name_version;
  }

  std::string extension_name;
  std::string extension_type;
  if (!GetExtensionInfo(web_contents, &extension_name, &extension_type)) {
    return std::string();
  }

  return extension_name;
}

std::unique_ptr<base::DictValue>
ChromeDevToolsManagerDelegate::GetTargetEmbedderData(
    content::DevToolsAgentHost* agent_host) {
  if (agent_host->GetType() != DevToolsAgentHost::kTypeTab) {
    return nullptr;
  }

  content::WebContents* web_contents = agent_host->GetWebContents();
  if (!web_contents) {
    return nullptr;
  }

  tabs::TabInterface* tab =
      tabs::TabInterface::MaybeGetFromContents(web_contents);
  if (!tab) {
    return nullptr;
  }

  BrowserWindowInterface* browser = tab->GetBrowserWindowInterface();
  if (!browser) {
    return nullptr;
  }

  TabStripModel* tab_strip_model = browser->GetTabStripModel();
  const int index = tab_strip_model->GetIndexOfTab(tab);
  if (index == TabStripModel::kNoTab) {
    return nullptr;
  }

  auto embedder_data = std::make_unique<base::DictValue>();
  embedder_data->Set("tabStripIndex", index);
  embedder_data->Set("tabActive", tab->IsActivated());
  embedder_data->Set("tabPinned", tab->IsPinned());
  std::optional<tab_groups::TabGroupId> group_id = tab->GetGroup();
  if (group_id.has_value()) {
    embedder_data->Set("tabGroupId", group_id->ToString());
  }
  return embedder_data;
}

bool ChromeDevToolsManagerDelegate::AllowInspectingRenderFrameHost(
    content::RenderFrameHost* rfh) {
  Profile* profile =
      Profile::FromBrowserContext(rfh->GetProcess()->GetBrowserContext());
  return IsInspectionAllowed(profile,
                             content::WebContents::FromRenderFrameHost(rfh));
}

bool ChromeDevToolsManagerDelegate::AllowInspectingTarget(
    content::DevToolsAgentHost* agent_host) {
  // For Android, we have the same implementation
  // in DevToolsManagerDelegateAndroid.
  Profile* profile =
      Profile::FromBrowserContext(agent_host->GetBrowserContext());
  if (!profile) {
    return true;
  }
  return IsInspectionAllowed(profile, agent_host);
}

void ChromeDevToolsManagerDelegate::ClientAttached(
    content::DevToolsAgentHostClientChannel* channel) {
  DCHECK(sessions_.find(channel) == sessions_.end());
  sessions_.emplace(channel, std::make_unique<ChromeDevToolsSession>(channel));
}

void ChromeDevToolsManagerDelegate::ClientDetached(
    content::DevToolsAgentHostClientChannel* channel) {
  sessions_.erase(channel);
}

scoped_refptr<DevToolsAgentHost> ChromeDevToolsManagerDelegate::CreateNewTarget(
    const GURL& url,
    DevToolsManagerDelegate::TargetType target_type,
    bool new_window) {
  NavigateParams params(ProfileManager::GetLastUsedProfile(), url,
                        ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
  params.disposition = WindowOpenDisposition::NEW_FOREGROUND_TAB;
  Navigate(&params);
  if (!params.navigated_or_inserted_contents)
    return nullptr;
  return target_type == DevToolsManagerDelegate::kTab
             ? DevToolsAgentHost::GetOrCreateForTab(
                   params.navigated_or_inserted_contents)
             : DevToolsAgentHost::GetOrCreateFor(
                   params.navigated_or_inserted_contents);
}

std::vector<base::WeakPtr<content::BrowserContext>>
ChromeDevToolsManagerDelegate::GetBrowserContexts() {
  return DevToolsBrowserContextManager::GetInstance().GetBrowserContexts();
}

content::BrowserContext*
ChromeDevToolsManagerDelegate::GetDefaultBrowserContext() {
  return DevToolsBrowserContextManager::GetInstance()
      .GetDefaultBrowserContext();
}

content::BrowserContext* ChromeDevToolsManagerDelegate::GetBrowserContext(
    const std::string& context_id) {
  return DevToolsBrowserContextManager::GetInstance().GetProfileById(
      context_id);
}

content::BrowserContext* ChromeDevToolsManagerDelegate::CreateBrowserContext() {
  return DevToolsBrowserContextManager::GetInstance().CreateBrowserContext();
}

void ChromeDevToolsManagerDelegate::DisposeBrowserContext(
    content::BrowserContext* context,
    DisposeCallback callback) {
  DevToolsBrowserContextManager::GetInstance().DisposeBrowserContext(
      context, std::move(callback));
}

bool ChromeDevToolsManagerDelegate::HasBundledFrontendResources() {
  return true;
}

void ChromeDevToolsManagerDelegate::DevicesAvailable(
    const DevToolsDeviceDiscovery::CompleteDevices& devices) {
  DevToolsAgentHost::List remote_targets;
  for (const auto& complete : devices) {
    for (const auto& browser : complete.second->browsers()) {
      for (const auto& page : browser->pages())
        remote_targets.push_back(page->CreateTarget());
    }
  }
  remote_agent_hosts_.swap(remote_targets);
}

void ChromeDevToolsManagerDelegate::UpdateDeviceDiscovery() {
  RemoteLocations remote_locations;
  for (const auto& it : sessions_) {
    TargetHandler* target_handler = it.second->target_handler();
    if (!target_handler)
      continue;
    RemoteLocations& locations = target_handler->remote_locations();
    remote_locations.insert(locations.begin(), locations.end());
  }

  if (remote_locations == remote_locations_) {
    return;
  }

  if (remote_locations.empty()) {
    device_discovery_.reset();
    remote_agent_hosts_.clear();
  } else {
    if (!device_manager_)
      device_manager_ = AndroidDeviceManager::Create();

    AndroidDeviceManager::DeviceProviders providers;
    providers.push_back(new TCPDeviceProvider(remote_locations));
    device_manager_->SetDeviceProviders(providers);

    device_discovery_ = std::make_unique<DevToolsDeviceDiscovery>(
        device_manager_.get(),
        base::BindRepeating(&ChromeDevToolsManagerDelegate::DevicesAvailable,
                            base::Unretained(this)));
  }
  remote_locations_.swap(remote_locations);
}

void ChromeDevToolsManagerDelegate::AcceptDebugging(AcceptCallback callback) {
  auto wrapped_callback = base::BindOnce(
      [](AcceptCallback inner_callback,
         content::DevToolsManagerDelegate::AcceptConnectionResult result) {
        bool allowed =
            result ==
            content::DevToolsManagerDelegate::AcceptConnectionResult::kAllow;
        base::UmaHistogramEnumeration(
            "DevTools.RemoteDebugging.ConnectionPermission",
            allowed ? DevToolsRemoteDebuggingConnectionPermission::kAllowed
                    : DevToolsRemoteDebuggingConnectionPermission::kDenied);
        std::move(inner_callback).Run(result);
      },
      std::move(callback));
  Profile* profile = Profile::FromBrowserContext(GetDefaultBrowserContext());
  ProfileBrowserCollection* collection =
      profile ? ProfileBrowserCollection::GetForProfile(profile) : nullptr;
  BrowserWindowInterface* last_active =
      collection ? collection->GetLastActiveBrowser() : nullptr;
  DevToolsConnectionDialog::Show(last_active, std::move(wrapped_callback));
}

void ChromeDevToolsManagerDelegate::SetActiveWebSocketConnections(
    size_t count) {
  if (count == 0 && infobar_) {
    // We need to reset the pointer to the infobar before closing it because
    // closing the infobar deletes it.
    auto* infobar = infobar_.get();
    infobar_ = nullptr;
    infobar->Close();
  } else if (count > 0 && !infobar_) {
    auto delegate = std::make_unique<DevToolsRemoteServerInfobarDelegate>();
    delegate->AddObserver(this);
    infobar_ = GlobalConfirmInfoBar::Show(std::move(delegate));
  }
}

void ChromeDevToolsManagerDelegate::OnAccept() {
  infobar_ = nullptr;
}

void ChromeDevToolsManagerDelegate::OnDismiss() {
  infobar_ = nullptr;
}

void ChromeDevToolsManagerDelegate::ResetAndroidDeviceManagerForTesting() {
  device_manager_.reset();

  // We also need |device_discovery_| to go away because there may be a pending
  // task using a raw pointer to the DeviceManager we just deleted.
  device_discovery_.reset();
}

// static
void ChromeDevToolsManagerDelegate::CloseBrowserSoon() {
  content::GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE, base::BindOnce([]() {
        // Do not keep the application running anymore, we got an explicit
        // request to close.
        AllowBrowserToClose();
        chrome::ExitIgnoreUnloadHandlers();
      }));
}

// static
void ChromeDevToolsManagerDelegate::AllowBrowserToClose() {
  if (auto* instance = GetInstance()) {
    instance->keep_alive_.reset();
  }
}
