// Copyright 2020 the V8 project 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 "src/logging/metrics.h"

#include "include/v8-platform.h"

namespace v8 {
namespace internal {
namespace metrics {

class Recorder::Task : public v8::Task {
 public:
  explicit Task(const std::shared_ptr<Recorder>& recorder)
      : recorder_(recorder) {}

  void Run() override {
    std::queue<std::unique_ptr<Recorder::DelayedEventBase>> delayed_events;
    {
      base::MutexGuard lock_scope(&recorder_->lock_);
      delayed_events.swap(recorder_->delayed_events_);
    }
    while (!delayed_events.empty()) {
      delayed_events.front()->Run(recorder_);
      delayed_events.pop();
    }
  }

 private:
  std::shared_ptr<Recorder> recorder_;
};

void Recorder::SetRecorder(
    Isolate* isolate,
    const std::shared_ptr<v8::metrics::Recorder>& embedder_recorder) {
  foreground_task_runner_ = V8::GetCurrentPlatform()->GetForegroundTaskRunner(
      reinterpret_cast<v8::Isolate*>(isolate));
  CHECK_NULL(embedder_recorder_);
  embedder_recorder_ = embedder_recorder;
}

void Recorder::NotifyIsolateDisposal() {
  if (embedder_recorder_) {
    embedder_recorder_->NotifyIsolateDisposal();
  }
}

void Recorder::Delay(std::unique_ptr<Recorder::DelayedEventBase>&& event) {
  base::MutexGuard lock_scope(&lock_);
  bool was_empty = delayed_events_.empty();
  delayed_events_.push(std::move(event));
  if (was_empty) {
    foreground_task_runner_->PostDelayedTask(
        std::make_unique<Task>(shared_from_this()), 1.0);
  }
}

}  // namespace metrics
}  // namespace internal
}  // namespace v8
