// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "chrome/browser/resource_coordinator/resource_coordinator_render_process_probe.h"

#include <vector>

#include "base/bind.h"
#include "base/memory/ptr_util.h"
#include "base/values.h"
#include "build/build_config.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_process_host.h"
#include "content/public/common/service_manager_connection.h"
#include "services/resource_coordinator/public/cpp/process_resource_coordinator.h"
#include "services/resource_coordinator/public/cpp/resource_coordinator_features.h"
#include "services/resource_coordinator/public/interfaces/coordination_unit.mojom.h"

#if defined(OS_MACOSX)
#include "content/public/browser/browser_child_process_host.h"
#endif

namespace resource_coordinator {

namespace {

const int kDefaultMeasurementIntervalInSeconds = 1;

base::LazyInstance<ResourceCoordinatorRenderProcessProbe>::DestructorAtExit
    g_probe = LAZY_INSTANCE_INITIALIZER;

}  // namespace

RenderProcessInfo::RenderProcessInfo() = default;

RenderProcessInfo::~RenderProcessInfo() = default;

RenderProcessMetricsHandler::RenderProcessMetricsHandler() = default;

RenderProcessMetricsHandler::~RenderProcessMetricsHandler() = default;

class ResourceCoordinatorRenderProcessMetricsHandler
    : public RenderProcessMetricsHandler {
 public:
  ResourceCoordinatorRenderProcessMetricsHandler() = default;
  ~ResourceCoordinatorRenderProcessMetricsHandler() override = default;

  // Send collected metrics back to the |resource_coordinator| service
  // and initiates another render process metrics gather cycle.
  bool HandleMetrics(
      const RenderProcessInfoMap& render_process_info_map) override {
    for (auto& render_process_info_map_entry : render_process_info_map) {
      auto& render_process_info = render_process_info_map_entry.second;
      // TODO(oysteine): Move the multiplier used to avoid precision loss
      // into a shared location, when this property gets used.
      render_process_info.host->GetProcessResourceCoordinator()->SetCPUUsage(
          render_process_info.cpu_usage);
    }

    return true;
  }
};

ResourceCoordinatorRenderProcessProbe::ResourceCoordinatorRenderProcessProbe()
    : metrics_handler_(
          base::MakeUnique<ResourceCoordinatorRenderProcessMetricsHandler>()),
      interval_ms_(
          base::TimeDelta::FromSeconds(kDefaultMeasurementIntervalInSeconds)) {
  UpdateWithFieldTrialParams();
}

ResourceCoordinatorRenderProcessProbe::
    ~ResourceCoordinatorRenderProcessProbe() = default;

// static
ResourceCoordinatorRenderProcessProbe*
ResourceCoordinatorRenderProcessProbe::GetInstance() {
  return g_probe.Pointer();
}

// static
bool ResourceCoordinatorRenderProcessProbe::IsEnabled() {
  // Check that service_manager is active, GRC is enabled,
  // and render process CPU profiling is enabled.
  return content::ServiceManagerConnection::GetForProcess() != nullptr &&
         resource_coordinator::IsResourceCoordinatorEnabled() &&
         base::FeatureList::IsEnabled(features::kGRCRenderProcessCPUProfiling);
}

void ResourceCoordinatorRenderProcessProbe::StartGatherCycle() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (!ResourceCoordinatorRenderProcessProbe::IsEnabled()) {
    return;
  }

  timer_.Start(FROM_HERE, base::TimeDelta(), this,
               &ResourceCoordinatorRenderProcessProbe::
                   RegisterAliveRenderProcessesOnUIThread);
}

void ResourceCoordinatorRenderProcessProbe::
    RegisterAliveRenderProcessesOnUIThread() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);

  ++current_gather_cycle_;

  for (content::RenderProcessHost::iterator rph_iter =
           content::RenderProcessHost::AllHostsIterator();
       !rph_iter.IsAtEnd(); rph_iter.Advance()) {
    content::RenderProcessHost* host = rph_iter.GetCurrentValue();
    base::ProcessHandle handle = host->GetHandle();
    // Process may not be valid yet.
    if (handle == base::kNullProcessHandle) {
      continue;
    }

    auto& render_process_info = render_process_info_map_[handle];
    render_process_info.last_gather_cycle_active = current_gather_cycle_;

    if (render_process_info.metrics.get() == nullptr) {
#if defined(OS_MACOSX)
      render_process_info.metrics = base::ProcessMetrics::CreateProcessMetrics(
          handle, content::BrowserChildProcessHost::GetPortProvider());
#else
      render_process_info.metrics =
          base::ProcessMetrics::CreateProcessMetrics(handle);
#endif
      render_process_info.host = host;
    }
  }

  content::BrowserThread::PostTask(
      content::BrowserThread::IO, FROM_HERE,
      base::BindOnce(&ResourceCoordinatorRenderProcessProbe::
                         CollectRenderProcessMetricsOnIOThread,
                     base::Unretained(this)));
}

void ResourceCoordinatorRenderProcessProbe::
    CollectRenderProcessMetricsOnIOThread() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::IO);

  RenderProcessInfoMap::iterator iter = render_process_info_map_.begin();
  while (iter != render_process_info_map_.end()) {
    auto& render_process_info = iter->second;

    // If the last gather cycle the render process was marked as active is
    // not current then it is assumed dead and should not be measured anymore.
    if (render_process_info.last_gather_cycle_active == current_gather_cycle_) {
      render_process_info.cpu_usage =
          render_process_info.metrics->GetPlatformIndependentCPUUsage();
      ++iter;
    } else {
      render_process_info_map_.erase(iter++);
      continue;
    }
  }

  content::BrowserThread::PostTask(
      content::BrowserThread::UI, FROM_HERE,
      base::BindOnce(&ResourceCoordinatorRenderProcessProbe::
                         HandleRenderProcessMetricsOnUIThread,
                     base::Unretained(this)));
}

void ResourceCoordinatorRenderProcessProbe::
    HandleRenderProcessMetricsOnUIThread() {
  DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  if (metrics_handler_->HandleMetrics(render_process_info_map_)) {
    timer_.Start(FROM_HERE, interval_ms_, this,
                 &ResourceCoordinatorRenderProcessProbe::
                     RegisterAliveRenderProcessesOnUIThread);
  }
}

bool ResourceCoordinatorRenderProcessProbe::
    AllRenderProcessMeasurementsAreCurrentForTesting() const {
  for (auto& render_process_info_map_entry : render_process_info_map_) {
    auto& render_process_info = render_process_info_map_entry.second;
    if (render_process_info.last_gather_cycle_active != current_gather_cycle_ ||
        render_process_info.cpu_usage < 0.0) {
      return false;
    }
  }
  return true;
}

void ResourceCoordinatorRenderProcessProbe::UpdateWithFieldTrialParams() {
  int64_t interval_ms = GetGRCRenderProcessCPUProfilingIntervalInMs();

  if (interval_ms > 0) {
    interval_ms_ = base::TimeDelta::FromMilliseconds(interval_ms);
  }
}

}  // namespace resource_coordinator
