// Copyright 2016 Google Inc. 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
