/*
 * Copyright (C) 2020 The Android Open Source Project
 *
 * 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 INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
#define INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_

#include "perfetto/base/export.h"

#include "protos/perfetto/trace/track_event/track_event.pbzero.h"

#include <map>
#include <string>
#include <vector>

namespace perfetto {
namespace protos {
namespace pbzero {
class TracePacket_Decoder;
class TrackEvent;
class TrackEvent_Decoder;
}  // namespace pbzero
}  // namespace protos

// A helper for keeping track of incremental state when intercepting track
// events.
class PERFETTO_EXPORT_COMPONENT TrackEventStateTracker {
 public:
  ~TrackEventStateTracker();

  struct StackFrame {
    uint64_t timestamp{};

    // Only one of |name| and |name_iid| will be set.
    std::string name;
    uint64_t name_iid{};
    uint64_t name_hash{};

    // Only one of |category| and |category_iid| will be set.
    std::string category;
    uint64_t category_iid{};
  };

  struct Track {
    uint64_t uuid{};
    uint32_t index{};  // Ordinal number for the track in the tracing session.

    std::string name;
    int64_t pid{};
    int64_t tid{};

    // Opaque user data associated with the track.
    std::vector<uint8_t> user_data;

    // Stack of opened slices on this track.
    std::vector<StackFrame> stack;
  };

  // State for a single trace writer sequence (typically a single thread).
  struct SequenceState {
    // Trace packet sequence defaults.
    Track track;

    // Interned state.
#if PERFETTO_DCHECK_IS_ON()
    uint32_t sequence_id{};
#endif
    std::map<uint64_t /*iid*/, std::string> event_names;
    std::map<uint64_t /*iid*/, std::string> event_categories;
    std::map<uint64_t /*iid*/, std::string> debug_annotation_names;
    // Current absolute timestamp of the incremental clock.
    uint64_t most_recent_absolute_time_ns = 0;
    // default_clock_id == 0 means, no default clock_id is set.
    uint32_t default_clock_id = 0;
  };

  // State for the entire tracing session. Shared by all trace writer sequences
  // participating in the session.
  struct SessionState {
    // Non-thread-bound tracks.
    std::map<uint64_t /*uuid*/, Track> tracks;
  };

  // Represents a single decoded track event (without arguments).
  struct ParsedTrackEvent {
    explicit ParsedTrackEvent(
        const perfetto::protos::pbzero::TrackEvent::Decoder&);

    // Underlying event.
    const perfetto::protos::pbzero::TrackEvent::Decoder& track_event;

    // Event metadata.
    uint64_t timestamp_ns{};
    uint64_t duration_ns{};

    size_t stack_depth{};

    protozero::ConstChars category{};
    protozero::ConstChars name{};
    uint64_t name_hash{};
  };

  // Interface used by the tracker to access tracing session and sequence state
  // and to report parsed track events.
  class Delegate {
   public:
    virtual ~Delegate();

    // Called to retrieve the session-global state shared by all sequences. The
    // returned pointer must remain valid (locked) throughout the call to
    // |ProcessTracePacket|.
    virtual SessionState* GetSessionState() = 0;

    // Called when the metadata (e.g., name) for a track changes. |Track| can be
    // modified by the callback to attach user data.
    virtual void OnTrackUpdated(Track&) = 0;

    // If the packet given to |ProcessTracePacket| contains a track event, this
    // method is called to report the properties of that event. Note that memory
    // pointers in |TrackEvent| will only be valid during this call.
    virtual void OnTrackEvent(const Track&, const ParsedTrackEvent&) = 0;
  };

  // Process a single trace packet, reporting any contained track event back via
  // the delegate interface. |SequenceState| must correspond to the sequence
  // that was used to write the packet.
  static void ProcessTracePacket(Delegate&,
                                 SequenceState&,
                                 const protos::pbzero::TracePacket_Decoder&);

 private:
  static void UpdateIncrementalState(
      Delegate&,
      SequenceState&,
      const protos::pbzero::TracePacket_Decoder&);
};

}  // namespace perfetto

#endif  // INCLUDE_PERFETTO_TRACING_TRACK_EVENT_STATE_TRACKER_H_
