// Copyright 2015 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 "third_party/blink/renderer/core/dom/frame_request_callback_collection.h"

#include "third_party/blink/renderer/core/frame/web_feature.h"
#include "third_party/blink/renderer/core/inspector/inspector_trace_events.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"

namespace blink {

FrameRequestCallbackCollection::FrameRequestCallbackCollection(
    ExecutionContext* context)
    : context_(context) {}

FrameRequestCallbackCollection::CallbackId
FrameRequestCallbackCollection::RegisterFrameCallback(FrameCallback* callback) {
  FrameRequestCallbackCollection::CallbackId id = ++next_callback_id_;
  callback->SetIsCancelled(false);
  callback->SetId(id);
  frame_callbacks_.push_back(callback);

  TRACE_EVENT_INSTANT1("devtools.timeline", "RequestAnimationFrame",
                       TRACE_EVENT_SCOPE_THREAD, "data",
                       inspector_animation_frame_event::Data(context_, id));
  probe::AsyncTaskScheduledBreakable(context_, "requestAnimationFrame",
                                     callback->async_task_id());
  return id;
}

void FrameRequestCallbackCollection::CancelFrameCallback(CallbackId id) {
  for (wtf_size_t i = 0; i < frame_callbacks_.size(); ++i) {
    if (frame_callbacks_[i]->Id() == id) {
      probe::AsyncTaskCanceledBreakable(context_, "cancelAnimationFrame",
                                        frame_callbacks_[i]->async_task_id());
      frame_callbacks_.EraseAt(i);
      TRACE_EVENT_INSTANT1("devtools.timeline", "CancelAnimationFrame",
                           TRACE_EVENT_SCOPE_THREAD, "data",
                           inspector_animation_frame_event::Data(context_, id));
      return;
    }
  }
  for (const auto& callback : callbacks_to_invoke_) {
    if (callback->Id() == id) {
      probe::AsyncTaskCanceledBreakable(context_, "cancelAnimationFrame",
                                        callback->async_task_id());
      TRACE_EVENT_INSTANT1("devtools.timeline", "CancelAnimationFrame",
                           TRACE_EVENT_SCOPE_THREAD, "data",
                           inspector_animation_frame_event::Data(context_, id));
      callback->SetIsCancelled(true);
      // will be removed at the end of ExecuteCallbacks()
      return;
    }
  }
}

void FrameRequestCallbackCollection::ExecuteFrameCallbacks(
    double high_res_now_ms,
    double high_res_now_ms_legacy) {
  TRACE_EVENT0("blink",
               "FrameRequestCallbackCollection::ExecuteFrameCallbacks");

  // First, generate a list of callbacks to consider.  Callbacks registered from
  // this point on are considered only for the "next" frame, not this one.
  DCHECK(callbacks_to_invoke_.IsEmpty());
  swap(callbacks_to_invoke_, frame_callbacks_);

  for (const auto& callback : callbacks_to_invoke_) {
    // When the ExecutionContext is destroyed (e.g. an iframe is detached),
    // there is no path to perform wrapper tracing for the callbacks. In such a
    // case, the callback functions may already have been collected by V8 GC.
    // Since it's possible that a callback function being invoked detaches an
    // iframe, we need to check the condition for each callback.
    if (context_->IsContextDestroyed())
      break;
    if (callback->IsCancelled()) {
      // Another requestAnimationFrame callback already cancelled this one
      UseCounter::Count(context_,
                        WebFeature::kAnimationFrameCancelledWithinFrame);
      continue;
    }
    TRACE_EVENT1(
        "devtools.timeline", "FireAnimationFrame", "data",
        inspector_animation_frame_event::Data(context_, callback->Id()));
    probe::AsyncTask async_task(context_, callback->async_task_id());
    probe::UserCallback probe(context_, "requestAnimationFrame", AtomicString(),
                              true);
    if (callback->GetUseLegacyTimeBase())
      callback->Invoke(high_res_now_ms_legacy);
    else
      callback->Invoke(high_res_now_ms);
  }

  callbacks_to_invoke_.clear();
}

void FrameRequestCallbackCollection::Trace(Visitor* visitor) const {
  visitor->Trace(frame_callbacks_);
  visitor->Trace(callbacks_to_invoke_);
  visitor->Trace(context_);
}

V8FrameCallback::V8FrameCallback(V8FrameRequestCallback* callback)
    : callback_(callback) {}

void V8FrameCallback::Trace(blink::Visitor* visitor) const {
  visitor->Trace(callback_);
  FrameCallback::Trace(visitor);
}

void V8FrameCallback::Invoke(double highResTime) {
  callback_->InvokeAndReportException(nullptr, highResTime);
}

}  // namespace blink
