// Copyright 2016 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "cobalt/browser/web_module_stat_tracker.h"

#if defined(ENABLE_WEBDRIVER)
#include <sstream>
#endif  // ENABLE_WEBDRIVER

#include "base/strings/stringprintf.h"
#include "cobalt/base/tokens.h"
#include "cobalt/web/event.h"
#if defined(ENABLE_WEBDRIVER)
#include "cobalt/dom/global_stats.h"
#endif  // ENABLE_WEBDRIVER

namespace cobalt {
namespace browser {

WebModuleStatTracker::WebModuleStatTracker(const std::string& name,
                                           bool should_track_event_stats)
    : name_(name),
      should_track_event_stats_(should_track_event_stats),
      layout_stat_tracker_(new layout::LayoutStatTracker(name)),
      dom_stat_tracker_(new dom::DomStatTracker(name)),
      event_is_processing_(
          base::StringPrintf("Event.%s.IsProcessing", name.c_str()), false,
          "Nonzero when an event is being processed."),
      current_event_type_(kEventTypeInvalid),
      current_event_dispatched_event_(nullptr) {
  if (should_track_event_stats_) {
    event_stats_list_.reserve(kNumEventTypes);
    for (int i = 0; i < kNumEventTypes; ++i) {
      EventType event_type = static_cast<EventType>(i);
      event_stats_list_.emplace_back(new EventStats(base::StringPrintf(
          "%s.%s", name.c_str(), GetEventTypeName(event_type).c_str())));
    }
  }

  stop_watches_.reserve(kNumStopWatchTypes);
  for (int i = 0; i < kNumStopWatchTypes; ++i) {
    stop_watches_.push_back(
        base::StopWatch(i, base::StopWatch::kAutoStartOff, this));
  }
  stop_watch_durations_.resize(kNumStopWatchTypes, base::TimeDelta());
}

void WebModuleStatTracker::OnStartDispatchEvent(
    const scoped_refptr<web::Event>& event) {
  if (!should_track_event_stats_) {
    return;
  }

  // If an event is already being tracked, then don't track this event. It needs
  // to be allowed to finish.
  if (current_event_type_ != kEventTypeInvalid) {
    return;
  }

  // Determine the event type.
  if (event->type() == base::Tokens::keydown()) {
    current_event_type_ = kEventTypeKeyDown;
  } else if (event->type() == base::Tokens::keyup()) {
    current_event_type_ = kEventTypeKeyUp;
  } else if (event->type() == base::Tokens::pointerdown()) {
    current_event_type_ = kEventTypePointerDown;
  } else if (event->type() == base::Tokens::pointerup()) {
    current_event_type_ = kEventTypePointerUp;
  } else {
    current_event_type_ = kEventTypeInvalid;
  }

  // If this is a valid event type, then start tracking it.
  if (current_event_type_ != kEventTypeInvalid) {
    DCHECK(!event_is_processing_);

    event_is_processing_ = true;
    current_event_dispatched_event_ = event;
    current_event_start_time_ = base::TimeTicks::Now();
    current_event_render_tree_produced_time_ = base::TimeTicks();

    dom_stat_tracker_->StartTrackingEvent();
    layout_stat_tracker_->StartTrackingEvent();

    stop_watch_durations_[kStopWatchTypeDispatchEvent] = base::TimeDelta();
    stop_watches_[kStopWatchTypeDispatchEvent].Start();
  }
}

void WebModuleStatTracker::OnStopDispatchEvent(
    const scoped_refptr<web::Event>& event,
    bool are_animation_frame_callbacks_pending,
    bool is_new_render_tree_pending) {
  // Verify that this dispatched event is the one currently being tracked.
  if (event != current_event_dispatched_event_) {
    return;
  }

  current_event_dispatched_event_ = nullptr;
  stop_watches_[kStopWatchTypeDispatchEvent].Stop();

  if (!are_animation_frame_callbacks_pending && !is_new_render_tree_pending &&
      current_event_render_tree_produced_time_.is_null()) {
    EndCurrentEvent(base::TimeTicks::Now());
  }
}

void WebModuleStatTracker::OnRanAnimationFrameCallbacks(
    bool is_new_render_tree_pending) {
  if (current_event_type_ == kEventTypeInvalid) {
    return;
  }

  if (!is_new_render_tree_pending &&
      current_event_render_tree_produced_time_.is_null()) {
    EndCurrentEvent(base::TimeTicks::Now());
  }
}

void WebModuleStatTracker::OnRenderTreeProduced(
    const base::TimeTicks& produced_time) {
  // Flush the periodic tracking regardless of whether or not there is a current
  // event. Periodic tracking is not tied to events.
  dom_stat_tracker_->FlushPeriodicTracking();
  layout_stat_tracker_->FlushPeriodicTracking();

  if (current_event_type_ == kEventTypeInvalid) {
    return;
  }

  // Event tracking stops when the first render tree being produced. At that
  // point, processing switches to the rasterizer thread and any subsequent
  // dom/layout work that occurs will not be associated with the event's first
  // render tree.
  if (current_event_render_tree_produced_time_.is_null()) {
    current_event_render_tree_produced_time_ = produced_time;
    dom_stat_tracker_->StopTrackingEvent();
    layout_stat_tracker_->StopTrackingEvent();
  }
}

void WebModuleStatTracker::OnRenderTreeRasterized(
    const base::TimeTicks& produced_time,
    const base::TimeTicks& rasterized_time) {
  if (current_event_type_ == kEventTypeInvalid) {
    return;
  }

  // End the event if the event's render tree has already been produced and
  // the rasterized render tree is not older than the event's render tree.
  if (!current_event_render_tree_produced_time_.is_null() &&
      produced_time >= current_event_render_tree_produced_time_) {
    EndCurrentEvent(rasterized_time);
  }
}

WebModuleStatTracker::EventStats::EventStats(const std::string& name)
    : start_time(base::StringPrintf("Event.Time.%s.Start", name.c_str()), 0,
                 "The time that the event started."),
      produced_render_tree(
          base::StringPrintf("Event.%s.ProducedRenderTree", name.c_str()),
          false, "Nonzero when the event produced a render tree."),
      count_dom_html_element(
          base::StringPrintf("Event.Count.%s.DOM.HtmlElement", name.c_str()), 0,
          "Total number of HTML elements."),
      count_dom_html_element_created(
          base::StringPrintf("Event.Count.%s.DOM.HtmlElement.Created",
                             name.c_str()),
          0, "Total number of HTML elements created."),
      count_dom_html_element_destroyed(
          base::StringPrintf("Event.Count.%s.DOM.HtmlElement.Destroyed",
                             name.c_str()),
          0, "Total number of HTML elements destroyed."),
      count_dom_html_element_document(
          base::StringPrintf("Event.Count.%s.DOM.HtmlElement.Document",
                             name.c_str()),
          0, "Number of HTML elements in document."),
      count_dom_html_element_document_added(
          base::StringPrintf("Event.Count.%s.DOM.HtmlElement.Document.Added",
                             name.c_str()),
          0, "Number of HTML elements added to document."),
      count_dom_html_element_document_removed(
          base::StringPrintf("Event.Count.%s.DOM.HtmlElement.Document.Removed",
                             name.c_str()),
          0, "Number of HTML elements removed from document."),
      count_dom_update_matching_rules(
          base::StringPrintf(
              "Event.Count.%s.DOM.HtmlElement.UpdateMatchingRules",
              name.c_str()),
          0, "Number of HTML elements that had their matching rules updated."),
      count_dom_update_computed_style(
          base::StringPrintf(
              "Event.Count.%s.DOM.HtmlElement.UpdateComputedStyle",
              name.c_str()),
          0, "Number of HTML elements that had their computed style updated."),
      count_dom_generate_html_element_computed_style(
          base::StringPrintf(
              "Event.Count.%s.DOM.HtmlElement.GenerateHtmlElementComputedStyle",
              name.c_str()),
          0,
          "Number of HTML elements that had their computed style generated."),
      count_dom_generate_pseudo_element_computed_style(
          base::StringPrintf("Event.Count.%s.DOM.HtmlElement."
                             "GeneratePseudoElementComputedStyle",
                             name.c_str()),
          0,
          "Number of pseudo elements that had their computed style generated."),
      count_layout_box(
          base::StringPrintf("Event.Count.%s.Layout.Box", name.c_str()), 0,
          "Number of layout boxes."),
      count_layout_box_created(
          base::StringPrintf("Event.Count.%s.Layout.Box.Created", name.c_str()),
          0, "Number of layout boxes created."),
      count_layout_box_destroyed(
          base::StringPrintf("Event.Count.%s.Layout.Box.Destroyed",
                             name.c_str()),
          0, "Number of layout boxes destroyed."),
      count_layout_update_size(
          base::StringPrintf("Event.Count.%s.Layout.Box.UpdateSize",
                             name.c_str()),
          0, "Number of layout boxes that had their size updated."),
      count_layout_render_and_animate(
          base::StringPrintf("Event.Count.%s.Layout.Box.RenderAndAnimate",
                             name.c_str()),
          0, "Number of layout boxes that had their render tree node updated."),
      count_layout_update_cross_references(
          base::StringPrintf("Event.Count.%s.Layout.Box.UpdateCrossReferences",
                             name.c_str()),
          0, "Number of layout boxes that had their cross references updated."),
      duration_total(base::StringPrintf("Event.Duration.%s", name.c_str()),
                     base::TimeDelta(),
                     "Total duration of the event (in microseconds). This is "
                     "the time elapsed from the event dispatch until the "
                     "render tree is produced."),
      duration_dom_dispatch_event(
          base::StringPrintf("Event.Duration.%s.DOM.DispatchEvent",
                             name.c_str()),
          base::TimeDelta(),
          "Dispatch duration, which includes JS, for event (in "
          "microseconds). This does not include subsequent DOM and Layout "
          "processing."),
      duration_dom_run_animation_frame_callbacks(
          base::StringPrintf("Event.Duration.%s.DOM.RunAnimationFrameCallbacks",
                             name.c_str()),
          base::TimeDelta(),
          "Run animation frame callbacks duration for event (in "
          "microseconds)."),
      duration_dom_update_computed_style(
          base::StringPrintf("Event.Duration.%s.DOM.UpdateComputedStyle",
                             name.c_str()),
          base::TimeDelta(),
          "UpdateComputedStyle duration for event (in microseconds)."),
      duration_layout_box_tree(
          base::StringPrintf("Event.Duration.%s.Layout.BoxTree", name.c_str()),
          base::TimeDelta(),
          "Layout box tree duration for event (in microseconds)."),
      duration_layout_box_generation(
          base::StringPrintf("Event.Duration.%s.Layout.BoxTree.BoxGeneration",
                             name.c_str()),
          base::TimeDelta(),
          "BoxGeneration duration for event (in microseconds)."),
      duration_layout_update_used_sizes(
          base::StringPrintf("Event.Duration.%s.Layout.BoxTree.UpdateUsedSizes",
                             name.c_str()),
          base::TimeDelta(),
          "UpdateUsedSizes duration for event (in microseconds)."),
      duration_layout_render_and_animate(
          base::StringPrintf("Event.Duration.%s.Layout.RenderAndAnimate",
                             name.c_str()),
          base::TimeDelta(),
          "RenderAndAnimate duration for event (in microseconds)."),
      duration_renderer_rasterize(
          base::StringPrintf("Event.Duration.%s.Renderer.Rasterize",
                             name.c_str()),
          base::TimeDelta(), "Rasterize duration for event (in microseconds).")
#if defined(ENABLE_WEBDRIVER)
      ,
      value_dictionary(
          base::StringPrintf("Event.%s.ValueDictionary", name.c_str()), "{}",
          "All event values represented as a dictionary in a string.")
#endif  // ENABLE_WEBDRIVER
{
}

bool WebModuleStatTracker::IsStopWatchEnabled(int id) const { return true; }

void WebModuleStatTracker::OnStopWatchStopped(int id,
                                              base::TimeDelta time_elapsed) {
  stop_watch_durations_[static_cast<size_t>(id)] += time_elapsed;
}

void WebModuleStatTracker::EndCurrentEvent(base::TimeTicks event_end_time) {
  if (current_event_type_ == kEventTypeInvalid) {
    return;
  }

  DCHECK(event_is_processing_);
  DCHECK(!current_event_start_time_.is_null());

  // If no render tree was produced by this event, then tracking stops at the
  // end of the event; otherwise, it already stopped when the render tree was
  // produced.
  if (current_event_render_tree_produced_time_.is_null()) {
    dom_stat_tracker_->StopTrackingEvent();
    layout_stat_tracker_->StopTrackingEvent();
  }

  // If a render tree was produced by this event, then the event is ending with
  // the render tree's rasterization; otherwise, there was no rasterization.
  base::TimeDelta renderer_rasterize_duration =
      !current_event_render_tree_produced_time_.is_null()
          ? event_end_time - current_event_render_tree_produced_time_
          : base::TimeDelta();

  EventStats* event_stats = event_stats_list_[current_event_type_].get();
  event_stats->start_time = current_event_start_time_.ToInternalValue();
  event_stats->produced_render_tree =
      !current_event_render_tree_produced_time_.is_null();

  // Update event counts
  event_stats->count_dom_html_element =
      dom_stat_tracker_->EventCountHtmlElement();
  event_stats->count_dom_html_element_created =
      dom_stat_tracker_->event_count_html_element_created();
  event_stats->count_dom_html_element_destroyed =
      dom_stat_tracker_->event_count_html_element_destroyed();
  event_stats->count_dom_html_element_document =
      dom_stat_tracker_->EventCountHtmlElementDocument();
  event_stats->count_dom_html_element_document_added =
      dom_stat_tracker_->event_count_html_element_document_added();
  event_stats->count_dom_html_element_document_removed =
      dom_stat_tracker_->event_count_html_element_document_removed();
  event_stats->count_dom_update_matching_rules =
      dom_stat_tracker_->event_count_update_matching_rules();
  event_stats->count_dom_update_computed_style =
      dom_stat_tracker_->event_count_update_computed_style();
  event_stats->count_dom_generate_html_element_computed_style =
      dom_stat_tracker_->event_count_generate_html_element_computed_style();
  event_stats->count_dom_generate_pseudo_element_computed_style =
      dom_stat_tracker_->event_count_generate_pseudo_element_computed_style();
  event_stats->count_layout_box = layout_stat_tracker_->EventCountBox();
  event_stats->count_layout_box_created =
      layout_stat_tracker_->event_count_box_created();
  event_stats->count_layout_box_destroyed =
      layout_stat_tracker_->event_count_box_destroyed();
  event_stats->count_layout_update_size =
      layout_stat_tracker_->event_count_update_size();
  event_stats->count_layout_render_and_animate =
      layout_stat_tracker_->event_count_render_and_animate();
  event_stats->count_layout_update_cross_references =
      layout_stat_tracker_->event_count_update_cross_references();

  // Update event durations
  event_stats->duration_total = event_end_time - current_event_start_time_;
  event_stats->duration_dom_dispatch_event =
      stop_watch_durations_[kStopWatchTypeDispatchEvent];
  event_stats->duration_dom_run_animation_frame_callbacks =
      dom_stat_tracker_->GetStopWatchTypeDuration(
          dom::DomStatTracker::kStopWatchTypeRunAnimationFrameCallbacks);
  event_stats->duration_dom_update_computed_style =
      dom_stat_tracker_->GetStopWatchTypeDuration(
          dom::DomStatTracker::kStopWatchTypeUpdateComputedStyle);
  event_stats->duration_layout_box_tree =
      layout_stat_tracker_->GetStopWatchTypeDuration(
          layout::LayoutStatTracker::kStopWatchTypeLayoutBoxTree);
  event_stats->duration_layout_box_generation =
      layout_stat_tracker_->GetStopWatchTypeDuration(
          layout::LayoutStatTracker::kStopWatchTypeBoxGeneration);
  event_stats->duration_layout_update_used_sizes =
      layout_stat_tracker_->GetStopWatchTypeDuration(
          layout::LayoutStatTracker::kStopWatchTypeUpdateUsedSizes);
  event_stats->duration_layout_render_and_animate =
      layout_stat_tracker_->GetStopWatchTypeDuration(
          layout::LayoutStatTracker::kStopWatchTypeRenderAndAnimate);
  event_stats->duration_renderer_rasterize = renderer_rasterize_duration;

#if defined(ENABLE_WEBDRIVER)
  // When the Webdriver is enabled, all of the event's values are stored
  // within a single string representing a dictionary of key-value pairs.
  // This allows the Webdriver to query a single CVal to retrieve all of the
  // event's values.
  std::ostringstream oss;
  oss << "{"
      << "\"StartTime\":" << current_event_start_time_.ToInternalValue() << ", "
      << "\"ProducedRenderTree\":"
      << !current_event_render_tree_produced_time_.is_null() << ", "
      << "\"CntDomEventListeners\":"
      << dom::GlobalStats::GetInstance()->GetNumEventListeners() << ", "
      << "\"CntDomNodes\":" << dom::GlobalStats::GetInstance()->GetNumNodes()
      << ", "
      << "\"CntDomHtmlElements\":" << dom_stat_tracker_->EventCountHtmlElement()
      << ", "
      << "\"CntDomDocumentHtmlElements\":"
      << dom_stat_tracker_->EventCountHtmlElementDocument() << ", "
      << "\"CntDomHtmlElementsCreated\":"
      << dom_stat_tracker_->event_count_html_element_created() << ", "
      << "\"CntDomUpdateMatchingRules\":"
      << dom_stat_tracker_->event_count_update_matching_rules() << ", "
      << "\"CntDomUpdateComputedStyle\":"
      << dom_stat_tracker_->event_count_update_computed_style() << ", "
      << "\"CntDomGenerateHtmlComputedStyle\":"
      << dom_stat_tracker_->event_count_generate_html_element_computed_style()
      << ", "
      << "\"CntDomGeneratePseudoComputedStyle\":"
      << dom_stat_tracker_->event_count_generate_pseudo_element_computed_style()
      << ", "
      << "\"CntLayoutBoxes\":" << layout_stat_tracker_->EventCountBox() << ", "
      << "\"CntLayoutBoxesCreated\":"
      << layout_stat_tracker_->event_count_box_created() << ", "
      << "\"CntLayoutUpdateSize\":"
      << layout_stat_tracker_->event_count_update_size() << ", "
      << "\"CntLayoutRenderAndAnimate\":"
      << layout_stat_tracker_->event_count_render_and_animate() << ", "
      << "\"CntLayoutUpdateCrossReferences\":"
      << layout_stat_tracker_->event_count_update_cross_references() << ", "
      << "\"DurTotalUs\":"
      << (event_end_time - current_event_start_time_).InMicroseconds() << ", "
      << "\"DurDomInjectEventUs\":"
      << stop_watch_durations_[kStopWatchTypeDispatchEvent].InMicroseconds()
      << ", "
      << "\"DurDomRunAnimationFrameCallbacksUs\":"
      << dom_stat_tracker_
             ->GetStopWatchTypeDuration(
                 dom::DomStatTracker::kStopWatchTypeRunAnimationFrameCallbacks)
             .InMicroseconds()
      << ", "
      << "\"DurDomUpdateComputedStyleUs\":"
      << dom_stat_tracker_
             ->GetStopWatchTypeDuration(
                 dom::DomStatTracker::kStopWatchTypeUpdateComputedStyle)
             .InMicroseconds()
      << ", "
      << "\"DurLayoutBoxTreeUs\":"
      << layout_stat_tracker_
             ->GetStopWatchTypeDuration(
                 layout::LayoutStatTracker::kStopWatchTypeLayoutBoxTree)
             .InMicroseconds()
      << ", "
      << "\"DurLayoutBoxTreeBoxGenerationUs\":"
      << layout_stat_tracker_
             ->GetStopWatchTypeDuration(
                 layout::LayoutStatTracker::kStopWatchTypeBoxGeneration)
             .InMicroseconds()
      << ", "
      << "\"DurLayoutBoxTreeUpdateUsedSizesUs\":"
      << layout_stat_tracker_
             ->GetStopWatchTypeDuration(
                 layout::LayoutStatTracker::kStopWatchTypeUpdateUsedSizes)
             .InMicroseconds()
      << ", "
      << "\"DurLayoutRenderAndAnimateUs\":"
      << layout_stat_tracker_
             ->GetStopWatchTypeDuration(
                 layout::LayoutStatTracker::kStopWatchTypeRenderAndAnimate)
             .InMicroseconds()
      << ", "
      << "\"DurRendererRasterizeUs\":"
      << renderer_rasterize_duration.InMicroseconds() << "}";
  event_stats->value_dictionary = oss.str();
#endif  // ENABLE_WEBDRIVER

  event_is_processing_ = false;
  current_event_type_ = kEventTypeInvalid;
}

std::string WebModuleStatTracker::GetEventTypeName(
    WebModuleStatTracker::EventType event_type) {
  switch (event_type) {
    case WebModuleStatTracker::kEventTypeKeyDown:
      return "KeyDown";
    case WebModuleStatTracker::kEventTypeKeyUp:
      return "KeyUp";
    case WebModuleStatTracker::kEventTypePointerDown:
      return "PointerDown";
    case WebModuleStatTracker::kEventTypePointerUp:
      return "PointerUp";
    case WebModuleStatTracker::kEventTypeInvalid:
    case WebModuleStatTracker::kNumEventTypes:
      break;
  }
  NOTREACHED();
  return "Invalid";
}

}  // namespace browser
}  // namespace cobalt
