// Copyright 2012 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/metrics/histogram_synchronizer.h"

#include <utility>

#include "base/check_op.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/location.h"
#include "base/metrics/histogram_delta_serialization.h"
#include "base/metrics/histogram_macros.h"
#include "base/no_destructor.h"
#include "base/pickle.h"
#include "base/task/single_thread_task_runner.h"
#include "base/threading/thread.h"
#include "components/metrics/histogram_controller.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/histogram_fetcher.h"
#include "content/public/common/content_constants.h"

namespace content {

using base::Time;
using base::TimeTicks;

namespace {

// Negative numbers are never used as sequence numbers.  We explicitly pick a
// negative number that is "so negative" that even when we add one (as is done
// when we generated the next sequence number) that it will still be negative.
// We have code that handles wrapping around on an overflow into negative
// territory.
static const int kNeverUsableSequenceNumber = -2;

}  // anonymous namespace

// The "RequestContext" structure describes an individual request received from
// the UI. All methods are accessible on UI thread.
class HistogramSynchronizer::RequestContext {
 public:
  // A map from sequence_number_ to the actual RequestContexts.
  typedef std::map<int, RequestContext*> RequestContextMap;

  RequestContext(base::OnceClosure callback, int sequence_number)
      : callback_(std::move(callback)),
        sequence_number_(sequence_number),
        received_process_group_count_(false),
        processes_pending_(0) {}
  ~RequestContext() {}

  void SetReceivedProcessGroupCount(bool done) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    received_process_group_count_ = done;
  }

  // Methods for book keeping of processes_pending_.
  void AddProcessesPending(int processes_pending) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    processes_pending_ += processes_pending;
  }

  void DecrementProcessesPending() {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);
    --processes_pending_;
  }

  // Records that we are waiting for one less histogram data from a process for
  // the given sequence number. If |received_process_group_count_| and
  // |processes_pending_| are zero, then delete the current object by calling
  // Unregister.
  void DeleteIfAllDone() {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);

    if (processes_pending_ <= 0 && received_process_group_count_)
      RequestContext::Unregister(sequence_number_);
  }

  // Register |callback| in |outstanding_requests_| map for the given
  // |sequence_number|.
  static void Register(base::OnceClosure callback, int sequence_number) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);

    RequestContext* request =
        new RequestContext(std::move(callback), sequence_number);
    GetOutstandingRequests()[sequence_number] = request;
  }

  // Find the |RequestContext| in |outstanding_requests_| map for the given
  // |sequence_number|.
  static RequestContext* GetRequestContext(int sequence_number) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);

    auto it = GetOutstandingRequests().find(sequence_number);
    if (it == GetOutstandingRequests().end()) {
      return nullptr;
    }

    RequestContext* request = it->second;
    DCHECK_EQ(sequence_number, request->sequence_number_);
    return request;
  }

  // Delete the entry for the given |sequence_number| from
  // |outstanding_requests_| map. This method is called when all changes have
  // been acquired, or when the wait time expires (whichever is sooner).
  static void Unregister(int sequence_number) {
    DCHECK_CURRENTLY_ON(BrowserThread::UI);

    auto it = GetOutstandingRequests().find(sequence_number);
    if (it == GetOutstandingRequests().end()) {
      return;
    }

    RequestContext* request = it->second;
    DCHECK_EQ(sequence_number, request->sequence_number_);
    std::move(request->callback_).Run();

    delete request;
    GetOutstandingRequests().erase(it);
  }

  // Delete all the entries in |outstanding_requests_| map.
  static void OnShutdown() {
    // Just in case we have any pending tasks, clear them out.
    while (!GetOutstandingRequests().empty()) {
      auto it = GetOutstandingRequests().begin();
      delete it->second;
      GetOutstandingRequests().erase(it);
    }
  }

  // Map of all outstanding RequestContexts, from sequence_number_ to
  // RequestContext.
  static RequestContextMap& GetOutstandingRequests() {
    static base::NoDestructor<RequestContextMap> outstanding_requests;
    return *outstanding_requests;
  }

  // Requests are made to asynchronously send data to the |callback_|.
  base::OnceClosure callback_;

  // The sequence number used by the most recent update request to contact all
  // processes.
  int sequence_number_;

  // Indicates if we have received all pending processes count.
  bool received_process_group_count_;

  // The number of pending processes (all renderer processes and browser child
  // processes) that have not yet responded to requests.
  int processes_pending_;
};

HistogramSynchronizer::HistogramSynchronizer()
    : lock_(),
      last_used_sequence_number_(kNeverUsableSequenceNumber),
      async_sequence_number_(kNeverUsableSequenceNumber) {
  metrics::HistogramController::GetInstance()->Register(this);
}

HistogramSynchronizer::~HistogramSynchronizer() {
  RequestContext::OnShutdown();

  // Just in case we have any pending tasks, clear them out.
  SetTaskRunnerAndCallback(nullptr, base::NullCallback());
}

HistogramSynchronizer* HistogramSynchronizer::GetInstance() {
  return base::Singleton<
      HistogramSynchronizer,
      base::LeakySingletonTraits<HistogramSynchronizer>>::get();
}

// static
void HistogramSynchronizer::FetchHistograms() {
  if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
    GetUIThreadTaskRunner({})->PostTask(
        FROM_HERE, base::BindOnce(&HistogramSynchronizer::FetchHistograms));
    return;
  }
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  HistogramSynchronizer* current_synchronizer =
      HistogramSynchronizer::GetInstance();
  if (current_synchronizer == nullptr)
    return;

  current_synchronizer->RegisterAndNotifyAllProcesses(
      HistogramSynchronizer::UNKNOWN, base::Minutes(1));
}

void FetchHistogramsAsynchronously(scoped_refptr<base::TaskRunner> task_runner,
                                   base::OnceClosure callback,
                                   base::TimeDelta wait_time) {
  HistogramSynchronizer::FetchHistogramsAsynchronously(
      std::move(task_runner), std::move(callback), wait_time);
}

// static
void HistogramSynchronizer::FetchHistogramsAsynchronously(
    scoped_refptr<base::TaskRunner> task_runner,
    base::OnceClosure callback,
    base::TimeDelta wait_time) {
  DCHECK(task_runner);
  DCHECK(callback);

  HistogramSynchronizer* current_synchronizer =
      HistogramSynchronizer::GetInstance();
  current_synchronizer->SetTaskRunnerAndCallback(std::move(task_runner),
                                                 std::move(callback));

  current_synchronizer->RegisterAndNotifyAllProcesses(
      HistogramSynchronizer::ASYNC_HISTOGRAMS, wait_time);
}

void HistogramSynchronizer::RegisterAndNotifyAllProcesses(
    ProcessHistogramRequester requester,
    base::TimeDelta wait_time) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  int sequence_number = GetNextAvailableSequenceNumber(requester);

  base::OnceClosure callback = base::BindOnce(
      &HistogramSynchronizer::ForceHistogramSynchronizationDoneCallback,
      base::Unretained(this), sequence_number);

  RequestContext::Register(std::move(callback), sequence_number);

  // Get histogram data from renderer and browser child processes.
  metrics::HistogramController::GetInstance()->GetHistogramData(
      sequence_number);

  // Post a task that would be called after waiting for wait_time.  This acts
  // as a watchdog, to cancel the requests for non-responsive processes.
  GetUIThreadTaskRunner({})->PostDelayedTask(
      FROM_HERE, base::BindOnce(&RequestContext::Unregister, sequence_number),
      wait_time);
}

void HistogramSynchronizer::OnPendingProcesses(int sequence_number,
                                               int pending_processes,
                                               bool end) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  RequestContext* request = RequestContext::GetRequestContext(sequence_number);
  if (!request)
    return;
  request->AddProcessesPending(pending_processes);
  request->SetReceivedProcessGroupCount(end);
  request->DeleteIfAllDone();
}

void HistogramSynchronizer::OnHistogramDataCollected(
    int sequence_number,
    const std::vector<std::string>& pickled_histograms) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  base::HistogramDeltaSerialization::DeserializeAndAddSamples(
      pickled_histograms);

  RequestContext* request = RequestContext::GetRequestContext(sequence_number);
  if (!request)
    return;

  // Delete request if we have heard back from all child processes.
  request->DecrementProcessesPending();
  request->DeleteIfAllDone();
}

void HistogramSynchronizer::SetTaskRunnerAndCallback(
    scoped_refptr<base::TaskRunner> task_runner,
    base::OnceClosure callback) {
  base::OnceClosure old_callback;
  scoped_refptr<base::TaskRunner> old_task_runner;
  {
    base::AutoLock auto_lock(lock_);
    old_callback = std::move(callback_);
    callback_ = std::move(callback);
    old_task_runner = std::move(callback_task_runner_);
    callback_task_runner_ = std::move(task_runner);
    // Prevent premature calling of our new callbacks.
    async_sequence_number_ = kNeverUsableSequenceNumber;
  }
  // Just in case there was a task pending....
  InternalPostTask(std::move(old_task_runner), std::move(old_callback));
}

void HistogramSynchronizer::ForceHistogramSynchronizationDoneCallback(
    int sequence_number) {
  base::OnceClosure callback;
  scoped_refptr<base::TaskRunner> task_runner;
  {
    base::AutoLock lock(lock_);
    if (sequence_number != async_sequence_number_)
      return;
    callback = std::move(callback_);
    task_runner = std::move(callback_task_runner_);
    callback_.Reset();
  }
  InternalPostTask(std::move(task_runner), std::move(callback));
}

void HistogramSynchronizer::InternalPostTask(
    scoped_refptr<base::TaskRunner> task_runner,
    base::OnceClosure callback) {
  if (callback.is_null() || !task_runner)
    return;
  task_runner->PostTask(FROM_HERE, std::move(callback));
}

int HistogramSynchronizer::GetNextAvailableSequenceNumber(
    ProcessHistogramRequester requester) {
  base::AutoLock auto_lock(lock_);
  ++last_used_sequence_number_;
  // Watch out for wrapping to a negative number.
  if (last_used_sequence_number_ < 0) {
    // Bypass the reserved number, which is used when a renderer spontaneously
    // decides to send some histogram data.
    last_used_sequence_number_ =
        kHistogramSynchronizerReservedSequenceNumber + 1;
  }
  DCHECK_NE(last_used_sequence_number_,
            kHistogramSynchronizerReservedSequenceNumber);
  if (requester == ASYNC_HISTOGRAMS)
    async_sequence_number_ = last_used_sequence_number_;
  return last_used_sequence_number_;
}

}  // namespace content
