// 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/dom/dom_stat_tracker.h"

#include "base/stringprintf.h"

namespace cobalt {
namespace dom {

DomStatTracker::DomStatTracker(const std::string& name)
    : count_html_element_(
          StringPrintf("Count.%s.DOM.HtmlElement", name.c_str()), 0,
          "Total number of HTML elements."),
      count_html_element_document_(
          StringPrintf("Count.%s.DOM.HtmlElement.Document", name.c_str()), 0,
          "Number of HTML elements in the document."),
      count_html_element_created_(0),
      count_html_element_destroyed_(0),
      count_html_element_document_added_(0),
      count_html_element_document_removed_(0),
      script_element_execute_count_(
          StringPrintf("Count.%s.DOM.HtmlScriptElement.Execute", name.c_str()),
          0, "Count of HTML script element execute calls."),
      script_element_execute_total_size_(
          StringPrintf("Memory.%s.DOM.HtmlScriptElement.Execute", name.c_str()),
          0, "Total size in bytes of HTML script elements executed."),
      script_element_execute_time_(
          StringPrintf("Time.%s.DOM.HtmlScriptElement.Execute", name.c_str()),
          0, "Time of the last HTML script element execute."),
      is_tracking_event_(false),
      event_initial_count_html_element_(0),
      event_initial_count_html_element_document_(0),
      event_count_html_element_created_(0),
      event_count_html_element_destroyed_(0),
      event_count_html_element_document_added_(0),
      event_count_html_element_document_removed_(0),
      event_count_update_matching_rules_(0),
      event_count_update_computed_style_(0),
      event_count_generate_html_element_computed_style_(0),
      event_count_generate_pseudo_element_computed_style_(0),
      event_video_start_delay_stop_watch_(kStopWatchTypeEventVideoStartDelay,
                                          base::StopWatch::kAutoStartOff, this),
      event_video_start_delay_(
          StringPrintf("Event.Duration.%s.DOM.VideoStartDelay", name.c_str()),
          base::TimeDelta(), "Total delay between event and video starting.") {
  stop_watch_durations_.resize(kNumStopWatchTypes, base::TimeDelta());
}

DomStatTracker::~DomStatTracker() {
  FlushPeriodicTracking();

  // Verify that all of the elements were removed from the document and
  // destroyed.
  DCHECK_EQ(count_html_element_, 0);
  DCHECK_EQ(count_html_element_document_, 0);

  event_video_start_delay_stop_watch_.Stop();
}

void DomStatTracker::OnHtmlElementCreated() {
  ++count_html_element_created_;
  if (is_tracking_event_) {
    ++event_count_html_element_created_;
  }
}

void DomStatTracker::OnHtmlElementDestroyed() {
  ++count_html_element_destroyed_;
  if (is_tracking_event_) {
    ++event_count_html_element_destroyed_;
  }
}

void DomStatTracker::OnHtmlElementInsertedIntoDocument() {
  ++count_html_element_document_added_;
  if (is_tracking_event_) {
    ++event_count_html_element_document_added_;
  }
}

void DomStatTracker::OnHtmlElementRemovedFromDocument() {
  ++count_html_element_document_removed_;
  if (is_tracking_event_) {
    ++event_count_html_element_document_removed_;
  }
}

void DomStatTracker::OnUpdateMatchingRules() {
  if (is_tracking_event_) {
    ++event_count_update_matching_rules_;
  }
}

void DomStatTracker::OnUpdateComputedStyle() {
  if (is_tracking_event_) {
    ++event_count_update_computed_style_;
  }
}

void DomStatTracker::OnGenerateHtmlElementComputedStyle() {
  if (is_tracking_event_) {
    ++event_count_generate_html_element_computed_style_;
  }
}

void DomStatTracker::OnGeneratePseudoElementComputedStyle() {
  if (is_tracking_event_) {
    ++event_count_generate_pseudo_element_computed_style_;
  }
}

void DomStatTracker::OnHtmlScriptElementExecuted(size_t script_size) {
  ++script_element_execute_count_;
  script_element_execute_total_size_ += script_size;
  script_element_execute_time_ = base::TimeTicks::Now().ToInternalValue();
}

void DomStatTracker::OnHtmlVideoElementPlaying() {
  if (event_video_start_delay_stop_watch_.IsCounting()) {
    event_video_start_delay_stop_watch_.Stop();
    event_video_start_delay_ =
        stop_watch_durations_[kStopWatchTypeEventVideoStartDelay];
  }
}

void DomStatTracker::FlushPeriodicTracking() {
  // Update the CVals before clearing the periodic values.
  count_html_element_ +=
      count_html_element_created_ - count_html_element_destroyed_;
  count_html_element_document_ +=
      count_html_element_document_added_ - count_html_element_document_removed_;

  // Now clear the values.
  count_html_element_created_ = 0;
  count_html_element_destroyed_ = 0;
  count_html_element_document_added_ = 0;
  count_html_element_document_removed_ = 0;
}

void DomStatTracker::StartTrackingEvent() {
  DCHECK(!is_tracking_event_);
  is_tracking_event_ = true;

  event_initial_count_html_element_ = count_html_element_ +
                                      count_html_element_created_ -
                                      count_html_element_destroyed_;
  event_initial_count_html_element_document_ =
      count_html_element_document_ + count_html_element_document_added_ -
      count_html_element_document_removed_;

  event_count_html_element_created_ = 0;
  event_count_html_element_destroyed_ = 0;
  event_count_html_element_document_added_ = 0;
  event_count_html_element_document_removed_ = 0;
  event_count_update_matching_rules_ = 0;
  event_count_update_computed_style_ = 0;
  event_count_generate_html_element_computed_style_ = 0;
  event_count_generate_pseudo_element_computed_style_ = 0;

  // Stop the watch before re-starting it. This ensures that the count is
  // zeroed out if it was still running from the prior event (this is a common
  // case as most events do not result in a video starting).
  event_video_start_delay_stop_watch_.Stop();
  event_video_start_delay_stop_watch_.Start();
  event_video_start_delay_ = base::TimeDelta();

  // Zero out the stop watch durations so that the numbers will only include the
  // event.
  for (size_t i = 0; i < kNumStopWatchTypes; ++i) {
    stop_watch_durations_[i] = base::TimeDelta();
  }
}

void DomStatTracker::StopTrackingEvent() {
  DCHECK(is_tracking_event_);
  is_tracking_event_ = false;
}

int DomStatTracker::EventCountHtmlElement() const {
  return event_initial_count_html_element_ + event_count_html_element_created_ -
         event_count_html_element_destroyed_;
}

int DomStatTracker::EventCountHtmlElementDocument() const {
  return event_initial_count_html_element_document_ +
         event_count_html_element_document_added_ -
         event_count_html_element_document_removed_;
}

base::TimeDelta DomStatTracker::GetStopWatchTypeDuration(
    StopWatchType type) const {
  return stop_watch_durations_[type];
}

bool DomStatTracker::IsStopWatchEnabled(int id) const {
  return is_tracking_event_ || id == kStopWatchTypeEventVideoStartDelay;
}

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

}  // namespace dom
}  // namespace cobalt
