// 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.

#ifndef COBALT_BROWSER_WEB_MODULE_STAT_TRACKER_H_
#define COBALT_BROWSER_WEB_MODULE_STAT_TRACKER_H_

#include <string>
#include <vector>

#include "base/memory/scoped_vector.h"
#include "base/time.h"
#include "cobalt/base/c_val.h"
#include "cobalt/base/stop_watch.h"
#include "cobalt/dom/dom_stat_tracker.h"
#include "cobalt/dom/event.h"
#include "cobalt/layout/layout_stat_tracker.h"

namespace cobalt {
namespace browser {

// This class handles tracking web module stats and is intended for single
// thread use. It also owns the |DomStatTracker| and |LayoutStatTracker|.
class WebModuleStatTracker : public base::StopWatchOwner {
 public:
  WebModuleStatTracker(const std::string& web_module_name,
                       bool should_track_dispatched_events);

  dom::DomStatTracker* dom_stat_tracker() const {
    return dom_stat_tracker_.get();
  }

  layout::LayoutStatTracker* layout_stat_tracker() const {
    return layout_stat_tracker_.get();
  }

  // |OnStartDispatchEvent| starts event stat tracking if
  // |should_track_dispatched_events_| is true. Otherwise, it does nothing.
  void OnStartDispatchEvent(const scoped_refptr<dom::Event>& event);

  // |OnStopDispatchEvent| notifies the event stat tracking that |event| has
  // finished being dispatched. If this is the event currently being tracked
  // and nothing is pending, then it also ends tracking of the event.
  void OnStopDispatchEvent(const scoped_refptr<dom::Event>& event,
                           bool are_animation_frame_callbacks_pending,
                           bool is_new_render_tree_pending);

  // |OnRanAnimationFrameCallbacks| ends stat tracking for the current event
  // if no render tree is pending.
  void OnRanAnimationFrameCallbacks(bool is_new_render_tree_pending);

  // |OnRenderTreeProduced| ends stat tracking for the current event.
  void OnRenderTreeProduced(const base::TimeTicks& produced_time);

  // |OnRenderTreeRasterized| ends stat tracking for the current event.
  void OnRenderTreeRasterized(const base::TimeTicks& produced_time,
                              const base::TimeTicks& rasterized_time);

  // Returns whether or not an event-based render tree has been produced but not
  // yet rasterized.
  bool IsRenderTreeRasterizationPending() const;

 private:
  enum EventType {
    kEventTypeInvalid = -1,
    kEventTypeKeyDown,
    kEventTypeKeyUp,
    kEventTypePointerDown,
    kEventTypePointerUp,
    kNumEventTypes,
  };

  enum StopWatchType {
    kStopWatchTypeDispatchEvent,
    kNumStopWatchTypes,
  };

  struct EventStats {
    explicit EventStats(const std::string& name);

    base::CVal<int64, base::CValPublic> start_time;
    base::CVal<bool, base::CValPublic> produced_render_tree;

    // Count-related
    base::CVal<int, base::CValPublic> count_dom_html_element;
    base::CVal<int, base::CValPublic> count_dom_html_element_created;
    base::CVal<int, base::CValPublic> count_dom_html_element_destroyed;
    base::CVal<int, base::CValPublic> count_dom_html_element_document;
    base::CVal<int, base::CValPublic> count_dom_html_element_document_added;
    base::CVal<int, base::CValPublic> count_dom_html_element_document_removed;
    base::CVal<int, base::CValPublic> count_dom_update_matching_rules;
    base::CVal<int, base::CValPublic> count_dom_update_computed_style;
    base::CVal<int, base::CValPublic>
        count_dom_generate_html_element_computed_style;
    base::CVal<int, base::CValPublic>
        count_dom_generate_pseudo_element_computed_style;
    base::CVal<int, base::CValPublic> count_layout_box;
    base::CVal<int, base::CValPublic> count_layout_box_created;
    base::CVal<int, base::CValPublic> count_layout_box_destroyed;
    base::CVal<int, base::CValPublic> count_layout_update_size;
    base::CVal<int, base::CValPublic> count_layout_render_and_animate;
    base::CVal<int, base::CValPublic> count_layout_update_cross_references;

    // Duration-related
    base::CVal<base::TimeDelta, base::CValPublic> duration_total;
    base::CVal<base::TimeDelta, base::CValPublic> duration_dom_dispatch_event;
    base::CVal<base::TimeDelta, base::CValPublic>
        duration_dom_run_animation_frame_callbacks;
    base::CVal<base::TimeDelta, base::CValPublic>
        duration_dom_update_computed_style;
    base::CVal<base::TimeDelta, base::CValPublic> duration_layout_box_tree;
    base::CVal<base::TimeDelta, base::CValPublic>
        duration_layout_box_generation;
    base::CVal<base::TimeDelta, base::CValPublic>
        duration_layout_update_used_sizes;
    base::CVal<base::TimeDelta, base::CValPublic>
        duration_layout_render_and_animate;
    base::CVal<base::TimeDelta, base::CValPublic> duration_renderer_rasterize;

#if defined(ENABLE_WEBDRIVER)
    // A string containing all of the event's values, excluding post-event
    // delays, as a dictionary of key-value pairs. This is used by the Webdriver
    // and is only enabled with it.
    base::CVal<std::string> value_dictionary;
#endif  // ENABLE_WEBDRIVER
  };

  // From base::StopWatchOwner
  bool IsStopWatchEnabled(int id) const override;
  void OnStopWatchStopped(int id, base::TimeDelta time_elapsed) override;

  // End the current event if one is active. This triggers an update of all
  // |EventStats| for the event.
  void EndCurrentEvent(base::TimeTicks end_time);

  static std::string GetEventTypeName(EventType event_type);

  const std::string name_;
  const bool should_track_event_stats_;

  // Web module owns the dom and layout stat trackers.
  scoped_ptr<dom::DomStatTracker> dom_stat_tracker_;
  scoped_ptr<layout::LayoutStatTracker> layout_stat_tracker_;

  // Event-related
  base::CVal<bool> event_is_processing_;
  EventType current_event_type_;
  // Raw pointer to the current event. This is used to verify that the event in
  // |OnStopDispatchEvent| is the dispatched event being tracked.
  dom::Event* current_event_dispatched_event_;
  base::TimeTicks current_event_start_time_;
  base::TimeTicks current_event_render_tree_produced_time_;

  // Each individual |EventType| has its own entry in the vector.
  ScopedVector<EventStats> event_stats_list_;

  // Stop watch-related
  std::vector<base::StopWatch> stop_watches_;
  std::vector<base::TimeDelta> stop_watch_durations_;
};

}  // namespace browser
}  // namespace cobalt

#endif  // COBALT_BROWSER_WEB_MODULE_STAT_TRACKER_H_
