// Copyright 2015 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/protocol/memory_handler.h"

#include <cinttypes>

#include "base/functional/bind.h"
#include "base/memory/memory_pressure_listener.h"
#include "base/profiler/module_cache.h"
#include "base/sampling_heap_profiler/sampling_heap_profiler.h"
#include "base/strings/stringprintf.h"
#include "content/public/browser/child_process_host.h"
#include "content/public/browser/render_process_host.h"

namespace content {
namespace protocol {

namespace {
constexpr char kAnotherLeakDetectionInProgress[] =
    "Another leak detection in progress";
constexpr char kNoProcessToDetectLeaksIn[] = "No process to detect leaks in";
constexpr char kFailedToRunLeakDetection[] = "Failed to run leak detection";
}  // namespace

MemoryHandler::MemoryHandler()
    : DevToolsDomainHandler(Memory::Metainfo::domainName),
      process_host_id_(ChildProcessHost::kInvalidUniqueID) {}

MemoryHandler::~MemoryHandler() = default;

void MemoryHandler::Wire(UberDispatcher* dispatcher) {
  Memory::Dispatcher::wire(dispatcher, this);
}

void MemoryHandler::SetRenderer(int process_host_id,
                                RenderFrameHostImpl* frame_host) {
  process_host_id_ = process_host_id;
}

Response MemoryHandler::GetBrowserSamplingProfile(
    std::unique_ptr<Memory::SamplingProfile>* out_profile) {
  base::ModuleCache module_cache;
  auto samples = std::make_unique<Array<Memory::SamplingProfileNode>>();
  std::vector<base::SamplingHeapProfiler::Sample> raw_samples =
      base::SamplingHeapProfiler::Get()->GetSamples(std::nullopt);

  for (auto& sample : raw_samples) {
    auto stack = std::make_unique<Array<String>>();
    for (const void* frame : sample.stack) {
      uintptr_t address = reinterpret_cast<uintptr_t>(frame);
      module_cache.GetModuleForAddress(address);  // Populates module_cache.
      stack->emplace_back(base::StringPrintf("0x%" PRIxPTR, address));
    }
    samples->emplace_back(Memory::SamplingProfileNode::Create()
                              .SetSize(sample.size)
                              .SetTotal(sample.total)
                              .SetStack(std::move(stack))
                              .Build());
  }

  auto modules = std::make_unique<Array<Memory::Module>>();
  for (const auto* module : module_cache.GetModules()) {
    modules->emplace_back(
        Memory::Module::Create()
            .SetName(base::StringPrintf(
                "%" PRFilePath, module->GetDebugBasename().value().c_str()))
            .SetUuid(module->GetId())
            .SetBaseAddress(
                base::StringPrintf("0x%" PRIxPTR, module->GetBaseAddress()))
            .SetSize(static_cast<double>(module->GetSize()))
            .Build());
  }

  *out_profile = Memory::SamplingProfile::Create()
                     .SetSamples(std::move(samples))
                     .SetModules(std::move(modules))
                     .Build();
  return Response::Success();
}

Response MemoryHandler::SetPressureNotificationsSuppressed(
    bool suppressed) {
  if (suppressed) {
    memory_pressure_suppression_token_.emplace();
  } else {
    memory_pressure_suppression_token_.reset();
  }
  return Response::Success();
}

Response MemoryHandler::SimulatePressureNotification(
    const std::string& level) {
  base::MemoryPressureLevel parsed_level;
  if (level == protocol::Memory::PressureLevelEnum::Moderate) {
    parsed_level = base::MEMORY_PRESSURE_LEVEL_MODERATE;
  } else if (level == protocol::Memory::PressureLevelEnum::Critical) {
    parsed_level = base::MEMORY_PRESSURE_LEVEL_CRITICAL;
  } else {
    return Response::InvalidParams(base::StringPrintf(
        "Invalid memory pressure level '%s'", level.c_str()));
  }

  // Simulate memory pressure notification in the browser process.
  base::MemoryPressureListener::SimulatePressureNotification(parsed_level);
  return Response::Success();
}

void MemoryHandler::PrepareForLeakDetection(
    std::unique_ptr<PrepareForLeakDetectionCallback> callback) {
  if (prepare_for_leak_detection_callback_ ||
      get_dom_counters_for_leak_detection_callback_) {
    callback->sendFailure(
        Response::ServerError(kAnotherLeakDetectionInProgress));
    return;
  }

  RenderProcessHost* process = RenderProcessHost::FromID(process_host_id_);
  if (!process) {
    callback->sendFailure(Response::ServerError(kNoProcessToDetectLeaksIn));
    return;
  }

  prepare_for_leak_detection_callback_ = std::move(callback);

  RequestLeakDetection(process);
}

void MemoryHandler::GetDOMCountersForLeakDetection(
    std::unique_ptr<GetDOMCountersForLeakDetectionCallback> callback) {
  if (prepare_for_leak_detection_callback_ ||
      get_dom_counters_for_leak_detection_callback_) {
    callback->sendFailure(
        Response::ServerError(kAnotherLeakDetectionInProgress));
    return;
  }

  RenderProcessHost* process = RenderProcessHost::FromID(process_host_id_);
  if (!process) {
    callback->sendFailure(Response::ServerError(kNoProcessToDetectLeaksIn));
    return;
  }

  get_dom_counters_for_leak_detection_callback_ = std::move(callback);

  RequestLeakDetection(process);
}

void MemoryHandler::RequestLeakDetection(RenderProcessHost* process) {
  process->BindReceiver(leak_detector_.BindNewPipeAndPassReceiver());

  // Using base::Unretained(this) in the code below is safe because the
  // callbacks are passed to the mojo remote member, so they are guaranteed
  // not to survive this.
  leak_detector_.set_disconnect_handler(base::BindOnce(
      &MemoryHandler::OnLeakDetectorIsGone, base::Unretained(this)));

  leak_detector_->PerformLeakDetection(base::BindOnce(
      &MemoryHandler::OnLeakDetectionComplete, base::Unretained(this)));
}

void MemoryHandler::OnLeakDetectionComplete(
    blink::mojom::LeakDetectionResultPtr result) {
  if (prepare_for_leak_detection_callback_) {
    prepare_for_leak_detection_callback_->sendSuccess();
    prepare_for_leak_detection_callback_.reset();
  }
  if (get_dom_counters_for_leak_detection_callback_) {
    if (result) {
      get_dom_counters_for_leak_detection_callback_->sendSuccess(
          GetDOMCounters(*result.get()));
    } else {
      get_dom_counters_for_leak_detection_callback_->sendFailure(
          Response::ServerError(kFailedToRunLeakDetection));
    }
    get_dom_counters_for_leak_detection_callback_.reset();
  }
  leak_detector_.reset();
}

void MemoryHandler::OnLeakDetectorIsGone() {
  if (prepare_for_leak_detection_callback_) {
    prepare_for_leak_detection_callback_->sendFailure(
        Response::ServerError(kFailedToRunLeakDetection));
    prepare_for_leak_detection_callback_.reset();
  }
  if (get_dom_counters_for_leak_detection_callback_) {
    get_dom_counters_for_leak_detection_callback_->sendFailure(
        Response::ServerError(kFailedToRunLeakDetection));
    get_dom_counters_for_leak_detection_callback_.reset();
  }
  leak_detector_.reset();
}

std::unique_ptr<protocol::Array<protocol::Memory::DOMCounter>>
MemoryHandler::GetDOMCounters(const blink::mojom::LeakDetectionResult& result) {
  auto counters =
      std::make_unique<protocol::Array<protocol::Memory::DOMCounter>>();

#define ADD_COUNTER(name)                                       \
  counters->emplace_back(protocol::Memory::DOMCounter::Create() \
                             .SetName(#name)                    \
                             .SetCount(result.number_of_##name) \
                             .Build());
  ADD_COUNTER(live_audio_nodes)
  ADD_COUNTER(live_documents)
  ADD_COUNTER(live_nodes)
  ADD_COUNTER(live_layout_objects)
  ADD_COUNTER(live_resources)
  ADD_COUNTER(live_context_lifecycle_state_observers)
  ADD_COUNTER(live_frames)
  ADD_COUNTER(live_v8_per_context_data)
  ADD_COUNTER(worker_global_scopes)
  ADD_COUNTER(live_ua_css_resources)
  ADD_COUNTER(live_resource_fetchers)

#undef ADD_COUNTER

  return counters;
}

}  // namespace protocol
}  // namespace content
