/*
 * 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 SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_FLOW_TRACKER_H_
#define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_FLOW_TRACKER_H_

#include <stdint.h>

#include "perfetto/ext/base/flat_hash_map.h"
#include "src/trace_processor/importers/common/args_tracker.h"
#include "src/trace_processor/storage/trace_storage.h"
#include "src/trace_processor/types/trace_processor_context.h"

namespace perfetto {
namespace trace_processor {

using FlowId = uint64_t;

class FlowTracker {
 public:
  explicit FlowTracker(TraceProcessorContext*);
  ~FlowTracker();

  void InsertFlow(SliceId slice_out_id, SliceId slice_in_id);

  // These methods track flow ids associated with slices and create flows as
  // needed.
  // If you don't have flow ids associated with slices, you should use the
  // InsertFlow method above.
  void Begin(SliceId slice_id, FlowId flow_id);
  void Step(SliceId slice_id, FlowId flow_id);
  void End(SliceId track_id, FlowId flow_id, bool close_flow);

  // These methods assume you have created a FlowId via GetFlowIdForV1Event and
  // tie the flow id to the currently open slice on a given track. If you don't
  // have a v1 event you should use the methods above.
  void Begin(TrackId track_id, FlowId flow_id);
  void Step(TrackId track_id, FlowId flow_id);

  // When |bind_enclosing_slice| is true we will connect the flow to the
  // currently open slice on the track, when false we will connect the flow to
  // the next slice to be opened on the track.
  // When |close_flow| is true it will mark this as the singular end of the
  // flow, however if there are multiple end points this should be set to
  // false. Both parameters are only needed for v1 flow events support
  void End(TrackId track_id,
           FlowId flow_id,
           bool bind_enclosing_slice,
           bool close_flow);

  bool IsActive(FlowId flow_id) const;

  FlowId GetFlowIdForV1Event(uint64_t source_id, StringId cat, StringId name);

  void ClosePendingEventsOnTrack(TrackId track_id, SliceId slice_id);

 private:
  struct V1FlowId {
    uint64_t source_id;
    StringId cat;
    StringId name;

    bool operator==(const V1FlowId& o) const {
      return o.source_id == source_id && o.cat == cat && o.name == name;
    }
  };

  struct V1FlowIdHasher {
    size_t operator()(const V1FlowId& c) const {
      return std::hash<uint64_t>{}(
          base::Hasher::Combine(c.source_id, c.cat.raw_id(), c.name.raw_id()));
    }
  };

  using FlowToSourceSliceMap = base::FlatHashMap<FlowId, SliceId>;
  using PendingFlowsMap = base::FlatHashMap<TrackId, std::vector<FlowId>>;
  using V1FlowIdToFlowIdMap =
      base::FlatHashMap<V1FlowId, FlowId, V1FlowIdHasher>;
  using FlowIdToV1FlowId = base::FlatHashMap<FlowId, V1FlowId>;

  void InsertFlow(FlowId flow_id,
                  SliceId outgoing_slice_id,
                  SliceId incoming_slice_id);

  // List of flow end calls waiting for the next slice
  PendingFlowsMap pending_flow_ids_map_;

  // Flows generated by Begin() or Step()
  FlowToSourceSliceMap flow_to_slice_map_;

  V1FlowIdToFlowIdMap v1_flow_id_to_flow_id_map_;
  FlowIdToV1FlowId flow_id_to_v1_flow_id_map_;
  uint32_t v1_id_counter_ = 0;

  TraceProcessorContext* const context_;

  StringId name_key_id_;
  StringId cat_key_id_;
};

}  // namespace trace_processor
}  // namespace perfetto

#endif  // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_FLOW_TRACKER_H_
