// Copyright 2015 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_TRACE_EVENT_EVENT_PARSER_H_
#define COBALT_TRACE_EVENT_EVENT_PARSER_H_

#include <set>
#include <string>
#include <vector>

#include "base/debug/trace_event.h"
#include "base/debug/trace_event_impl.h"
#include "base/hash_tables.h"
#include "base/memory/ref_counted.h"
#include "base/optional.h"
#include "base/time.h"

namespace cobalt {
namespace trace_event {

// EventParser is a class responsible for parsing raw base::debug::TraceLog
// trace events generated by calls to tracing functions found in trace_event.h.
// Example tracing calls include TRACE_EVENT0 and TRACE_EVENT_FLOW_BEGIN0.
// It parses raw sequences of base::debug::TraceEvent structures into
// high level event trees.
// This class will interpret the incoming log data and, as it becomes able to,
// will in turn fire its own higher level events such as when an event flow
// has ended.  This is useful because it compiles all data for flow structures
// as it reads the individual raw trace events and only provides it to the
// client when entire flows have completed and all relevant information about
// them is available and nicely organized.
// Using this trace log parse to re-create the program flow structure
// makes it much easier to write code that analyzes timing and execution results
// available in the trace log.
// EventParser can link TRACE_EVENTs across TRACE_EVENT_FLOWs, allowing entire
// processing pipelines that span multiple thread boundaries to be linked
// together automatically.
class EventParser {
 public:
  // A ScopedEvent represents some Chromium tracing event that has a duration.
  // This includes standard TRACE_EVENTs which are scoped and thus have a
  // beginning and end.  It also includes TRACE_EVENT_FLOWs, which necessarily
  // have an associated beginning and end.
  class ScopedEvent : public base::RefCountedThreadSafe<ScopedEvent> {
   public:
    ScopedEvent(const scoped_refptr<ScopedEvent>& parent,
                const base::debug::TraceEvent& begin_event,
                EventParser* event_parser);

    // Shortcut method to retrieve the event name.  This should be the same
    // amongst begin_event(), end_event() and all instant_events().
    const std::string name() const { return begin_event().name(); }

    // Convenience method for returning the duration of this event's entire
    // flow.  This value may not exist if the trace was terminated before the
    // end of the scoped event's flow occurs.
    base::optional<base::TimeDelta> flow_duration() const {
      if (end_flow_time()) {
        return *end_flow_time() - begin_event().timestamp();
      } else {
        return base::nullopt;
      }
    }

    // Convenience method for returning the duration of this event's scope.
    // This value may not exist if the trace was terminated before the
    // scoped event's end occurs.
    base::optional<base::TimeDelta> in_scope_duration() const {
      if (end_event()) {
        return end_event()->timestamp() - begin_event().timestamp();
      } else {
        return base::nullopt;
      }
    }

    // Returns the event's parent scope.  Informally, this is the scope that
    // was responsible for producing this scope.
    const scoped_refptr<ScopedEvent>& parent() const { return parent_; }

    // Return a list of the event's child events.  Informally, these are the
    // events that were produced by this event.
    const std::vector<scoped_refptr<ScopedEvent> > children() const {
      return children_;
    }

    // Returns the Chromium TraceEvent structure associated with the beginning
    // of this scoped event (e.g. since the event is scoped, it has a beginning
    // and end).
    const base::debug::TraceEvent& begin_event() const { return begin_event_; }

    // Returns the Chromium TraceEvent structure associated with the end of this
    // scoped event.  If the scoped event has not finished yet, this will return
    // nullopt.
    const base::optional<base::debug::TraceEvent>& end_event() const {
      return end_event_;
    }

    // Return a list of instant events that are effectively children of this
    // scoped event.  For example, all TRACE_EVENT_FLOW_STEP calls will attach
    // the generated TraceEvent structure as an instant event to the
    // corresponding flow ScopedEvent.
    const std::vector<base::debug::TraceEvent> instant_events() const {
      return instant_events_;
    }

    // The end flow time is the time when the last of this ScopedEvent's
    // descendants has ended.  This can be much later than the ScopedEvent's
    // local end time.  An example where the end flow time is different from
    // the end time is if within a TRACE_EVENT, a TRACE_EVENT_FLOW is started
    // and the TRACE_EVENT_FLOW ends *after* the TRACE_EVENT ends.  In this
    // case, the TRACE_EVENT's end flow time is equal to the TRACE_EVENT_FLOW's
    // end time, assuming the TRACE_EVENT_FLOW did not spawn any children of its
    // own that could extend the TRACE_EVENT's end flow time even longer.
    const base::optional<base::TimeTicks>& end_flow_time() const {
      return end_flow_time_;
    }

    // Returns the latest generated Chromium TraceEvent we've seen so far.
    // This will return end_event if it exists, otherwise the latest
    // instant_event, otherwise the begin_event.
    const base::debug::TraceEvent& LastTraceEvent() const;

    // The state is used to keep track of what state the ScopedEvent is in.
    // ScopedEvents may persist for much longer after they have been ended.
    // Newly started event scopes will begin life in the kState_Active state.
    enum State {
      // kState_Active means that the ScopedEvent has not yet received a
      // end signal (e.g. TRACE_EVENT_FLOW_BEGIN is not yet matched with
      // TRACE_EVENT_FLOW_END).
      kActiveState,
      // kState_Ended means that the ScopedEvent has received an end signal,
      // but it still has descendants that have not received their end signal
      // and thus the end flow time for this ScopedEvent is not currently
      // available.
      kEndedState,
      // kState_EndedAndLastTouched exists to handle a bit of a special case
      // where a TRACE_EVENT_FLOW is ended, and it has no children, but
      // since it can potentially be linked as a parent to a subsequent
      // TRACE_EVENT call (e.g. as is done in MessageLoop::RunTask), it should
      // not be marked as having its flow ended yet.  Being "last touched"
      // means that this event was last on a thread to be modified on any
      // thread (e.g. started, stepped or ended).
      kEndedAndLastTouchedState,
      // kState_FlowEnded indicates that this ScopedEvent and all its
      // descendants have ended their flows, and the state of the event will
      // no longer be changing.
      kFlowEndedState,
      // kState_Aborted indicates that the ScopedEvent did not end properly
      // and was instead aborted prematurely.  Not all fields (like end_event)
      // may be available, but the object will no longer be changing.
      kAbortedState,
    };
    State state() const { return state_; }

   private:
    virtual ~ScopedEvent();
    friend class base::RefCountedThreadSafe<ScopedEvent>;

    // Many of these methods will be called by EventParser in response to event
    // processing.
    void OnEnd(const base::debug::TraceEvent& end_event);
    void OnEndFlow(const base::TimeTicks& timestamp);
    bool AreEndFlowConditionsMet() const;
    void AddInstantEvent(const base::debug::TraceEvent& event);
    void OnNotLastTouched();
    void Abort();

    // Returns a set of all leaf nodes in the event tree rooted at this
    // ScopedEvent node.  If this node is a leaf node, the returned set
    // will contain this node as the single item.
    std::set<scoped_refptr<ScopedEvent> > GetLeafEvents();

    scoped_refptr<ScopedEvent> parent_;
    std::vector<scoped_refptr<ScopedEvent> > children_;

    base::debug::TraceEvent begin_event_;
    base::optional<base::debug::TraceEvent> end_event_;
    base::optional<base::TimeTicks> end_flow_time_;

    std::vector<base::debug::TraceEvent> instant_events_;

    // How many of our children have flows that have not ended yet?  If this
    // is non-zero, then our flow cannot yet be ended.
    int flow_active_children_;

    State state_;

    // The parent event parser this ScopedEvent is apart of.
    EventParser* event_parser_;

    friend class EventParser;
  };

  typedef base::Callback<void(const scoped_refptr<ScopedEvent>& event)>
      ScopedEventFlowEndCallback;

  // The passed in scoped_event_flow_end_callback will be run every time we
  // encounter a ScopedEvent whose flow has ended (e.g. the event is over and
  // so are all its descendants).  It is important to realize that an event's
  // "flow end" is different from the end of the event's scope.  For example,
  // if a TRACE_EVENT posts a message to a message loop, and then the
  // TRACE_EVENT goes out of scope, the event's scope has ended but its flow
  // has not.  The flow will only end when the posted message is processed
  // and that message did not post any messages of its own to extend the flow
  // farther.
  explicit EventParser(
      const ScopedEventFlowEndCallback& scoped_event_flow_end_callback);
  ~EventParser();

  // This is the function that drives the event parser.  As raw events are fed
  // to EventParser from base::debug::TraceLog, the event parser is updated and
  // may produce its own higher level events.
  void ParseEvent(const base::debug::TraceEvent& event);

 private:
  // Used to keep track of information local to specific threads, such as
  // which events are currently on the stack for that thread, and what the last
  // event touched on that thread was.
  struct ThreadInfo {
    std::vector<scoped_refptr<ScopedEvent> > event_stack_;
    scoped_refptr<ScopedEvent> last_touched_event_;
  };

  void UpdateLastTouchedEvent(ThreadInfo* thread_info,
                              const scoped_refptr<ScopedEvent>& event);

  std::set<scoped_refptr<ScopedEvent> > GetLeafEvents();

  friend class ScopedEvent;

  ScopedEventFlowEndCallback scoped_event_flow_end_callback_;

  typedef base::hash_map<int, ThreadInfo> ThreadMap;
  ThreadMap thread_id_to_info_map_;

  // Keep a mapping of all active flow events (which may span multiple threads)
  // for easy lookup if we need to process a flow event.
  typedef base::hash_map<uint64_t, scoped_refptr<ScopedEvent> > FlowEventMap;
  FlowEventMap flow_id_to_event_map_;
};

}  // namespace trace_event
}  // namespace cobalt

#endif  // COBALT_TRACE_EVENT_EVENT_PARSER_H_
