// Copyright 2017 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef GARNET_LIB_MEASURE_DURATION_H_
#define GARNET_LIB_MEASURE_DURATION_H_

#include <map>
#include <stack>
#include <unordered_map>
#include <vector>

#include <trace-reader/reader.h>

#include "garnet/lib/measure/event_spec.h"
#include "src/lib/fxl/macros.h"

namespace tracing {
namespace measure {

// A "duration" measurement specifies a single trace event. The target event can
// be recorded as a "duration" or as an "async" event.
struct DurationSpec {
  MeasurementSpecCommon common;
  EventSpec event;
};

class MeasureDuration {
 public:
  explicit MeasureDuration(std::vector<DurationSpec> specs);

  // Processes a recorded trace event. Returns true on success and false if the
  // record was ignored due to an error in the provided data. Trace events must
  // be processed in non-decreasing order of timestamps.
  bool Process(const trace::Record::Event& event);

  // Returns the results of the measurements. The results are represented as a
  // map of measurement ids to lists of time deltas representing the durations
  // of the matching trace events.
  const std::unordered_map<uint64_t, std::vector<uint64_t>>& results() { return results_; }

 private:
  // Async and flow event ids are scoped to event names. To match "end" events
  // with "begin" events, we keep a map of unmatched begin events.
  struct PendingBeginKey {
    enum class Type { Async, Flow };

    Type type;
    fbl::String category;
    fbl::String name;
    uint64_t id;

    bool operator<(const PendingBeginKey& other) const;
  };

  PendingBeginKey MakeKey(const trace::Record::Event& event);

  bool ProcessAsyncOrFlowBegin(const trace::Record::Event& event);
  bool ProcessAsyncOrFlowEnd(const trace::Record::Event& event);
  bool ProcessDurationBegin(const trace::Record::Event& event);
  bool ProcessDurationEnd(const trace::Record::Event& event);
  bool ProcessDurationComplete(const trace::Record::Event& event);

  void AddResult(uint64_t spec_id, trace_ticks_t from, trace_ticks_t to);

  std::vector<DurationSpec> specs_;
  std::unordered_map<uint64_t, std::vector<uint64_t>> results_;

  std::map<PendingBeginKey, trace_ticks_t> pending_begins_;

  // Duration events recorded on a thread can be nested. To match "end" events
  // with "begin" events, we keep a per-thread stack of timestamps of unmatched
  // "begin" events.
  std::map<trace::ProcessThread, std::stack<trace_ticks_t>> duration_stacks_;

  FXL_DISALLOW_COPY_AND_ASSIGN(MeasureDuration);
};

}  // namespace measure
}  // namespace tracing

#endif  // GARNET_LIB_MEASURE_DURATION_H_
