// 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 "content/browser/devtools/devtools_frontend_host_impl.h"

#include <stddef.h>

#include <memory>
#include <string>

#include "base/feature_list.h"
#include "base/memory/ref_counted_memory.h"
#include "base/strings/strcat.h"
#include "base/strings/string_view_util.h"
#include "base/strings/utf_string_conversions.h"
#include "build/build_config.h"
#include "content/browser/bad_message.h"
#include "content/browser/devtools/grit/devtools_resources_map.h"
#include "content/common/features.h"
#include "content/public/browser/render_frame_host.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_client.h"
#include "content/public/common/url_constants.h"
#include "third_party/blink/public/common/associated_interfaces/associated_interface_provider.h"
#include "ui/base/webui/resource_path.h"

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include "components/crash/content/browser/error_reporting/javascript_error_report.h"  // nogncheck
#include "components/crash/content/browser/error_reporting/js_error_report_processor.h"  // nogncheck
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

namespace content {
namespace {
const char kCompatibilityScript[] = "devtools_compatibility.js";
const char kCompatibilityScriptSourceURL[] =
    "\n//# "
    "sourceURL=devtools://devtools/bundled/devtools_compatibility.js";

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
// Remove the pieces of the URL we don't want to send back with the error
// reports. In particular, do not send query or fragments as those can have
// privacy-sensitive information in them.
std::string RedactURL(const GURL& url) {
  std::string redacted_url = url.DeprecatedGetOriginAsURL().spec();
  // Path will start with / and GetOrigin ends with /. Cut one / to avoid
  // chrome://discards//graph.
  if (!redacted_url.empty() && redacted_url.back() == '/') {
    redacted_url.pop_back();
  }
  base::StrAppend(&redacted_url, {url.path()});
  return redacted_url;
}
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
}

// static
std::unique_ptr<DevToolsFrontendHost> DevToolsFrontendHost::Create(
    RenderFrameHost* frame_host,
    const HandleMessageCallback& handle_message_callback) {
  DCHECK(!frame_host->GetParent());
  return std::make_unique<DevToolsFrontendHostImpl>(frame_host,
                                                    handle_message_callback);
}

// static
std::unique_ptr<DevToolsFrontendHostImpl>
DevToolsFrontendHostImpl::CreateForTesting(
    RenderFrameHost* frame_host,
    const HandleMessageCallback& handle_message_callback) {
  DCHECK(!frame_host->GetParent());
  return std::make_unique<DevToolsFrontendHostImpl>(frame_host,
                                                    handle_message_callback);
}

// static
void DevToolsFrontendHost::SetupExtensionsAPI(
    RenderFrameHost* frame_host,
    const std::string& extension_api) {
  DCHECK(frame_host->GetParent());
  mojo::AssociatedRemote<blink::mojom::DevToolsFrontend> frontend;
  frame_host->GetRemoteAssociatedInterfaces()->GetInterface(&frontend);
  frontend->SetupDevToolsExtensionAPI(extension_api);
}

// static
scoped_refptr<base::RefCountedMemory>
DevToolsFrontendHost::GetFrontendResourceBytes(const std::string& path) {
  for (const auto& [resource_path, id, filepath] : kDevtoolsResources) {
    if (path == resource_path) {
      return GetContentClient()->GetDataResourceBytes(id);
    }
  }
  return nullptr;
}

// static
std::string DevToolsFrontendHost::GetFrontendResource(const std::string& path) {
  scoped_refptr<base::RefCountedMemory> bytes = GetFrontendResourceBytes(path);
  if (!bytes)
    return std::string();
  return std::string(base::as_string_view(*bytes));
}

DevToolsFrontendHostImpl::DevToolsFrontendHostImpl(
    RenderFrameHost* frame_host,
    const HandleMessageCallback& handle_message_callback)
    : WebContentsObserver(WebContents::FromRenderFrameHost(frame_host)),
      handle_message_callback_(handle_message_callback) {
  mojo::AssociatedRemote<blink::mojom::DevToolsFrontend> frontend;
  frame_host->GetRemoteAssociatedInterfaces()->GetInterface(&frontend);
  std::string api_script =
      content::DevToolsFrontendHost::GetFrontendResource(kCompatibilityScript) +
      kCompatibilityScriptSourceURL;
  frontend->SetupDevToolsFrontend(api_script,
                                  receiver_.BindNewEndpointAndPassRemote());
}

DevToolsFrontendHostImpl::~DevToolsFrontendHostImpl() = default;

void DevToolsFrontendHostImpl::BadMessageReceived() {
  if (!web_contents()) {
    return;
  }

  bad_message::ReceivedBadMessage(
      web_contents()->GetPrimaryMainFrame()->GetProcess(),
      bad_message::DFH_BAD_EMBEDDER_MESSAGE);
}

void DevToolsFrontendHostImpl::DispatchEmbedderMessage(
    base::Value::Dict message) {
  handle_message_callback_.Run(std::move(message));
}

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
void DevToolsFrontendHostImpl::OnDidAddMessageToConsole(
    RenderFrameHost* source_frame,
    blink::mojom::ConsoleMessageLevel log_level,
    const std::u16string& message,
    int32_t line_no,
    const std::u16string& source_id,
    const std::optional<std::u16string>& untrusted_stack_trace) {
  if (!base::FeatureList::IsEnabled(
          features::kEnableDevToolsJsErrorReporting)) {
    return;
  }

  DVLOG(3) << "OnDidAddMessageToConsole called for " << message;

  if (log_level != blink::mojom::ConsoleMessageLevel::kError) {
    DVLOG(3) << "Message not reported, not an error";
    return;
  }

  scoped_refptr<JsErrorReportProcessor> processor =
      JsErrorReportProcessor::Get();
  if (!processor) {
    // This usually means we are not on an official Google build, FYI.
    DVLOG(3) << "Message not reported, no processor";
    return;
  }

  GURL url(source_id);
  if (!url.is_valid()) {
    DVLOG(3) << "Message not reported, invalid URL: " << source_id;
    return;
  }

  // If this is not a devtools:// page, do not report the error
  // This allows us to filter out messages from web page and extensions.
  // Even extensions are part of the DevTools (via
  // chrome.devtools.panels.create) the source for logs from them starts with
  // `chrome-extension://`
  if (!url.SchemeIs(kChromeDevToolsScheme)) {
    DVLOG(3) << "Message not reported, not a devtools:// URL";
    return;
  }

  JavaScriptErrorReport report;
  report.message = base::UTF16ToUTF8(message);
  report.line_number = line_no;
  report.url = RedactURL(url);
  report.source_system = JavaScriptErrorReport::SourceSystem::kDevToolsObserver;
  if (untrusted_stack_trace) {
    report.stack_trace = base::UTF16ToUTF8(*untrusted_stack_trace);
  }

  processor->SendErrorReport(std::move(report), base::DoNothing(),
                             web_contents()->GetBrowserContext());
}
#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

}  // namespace content
