// 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(0);

  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
