// Copyright 2020 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 SRC_TESTING_LOADBENCH_TRACING_H_
#define SRC_TESTING_LOADBENCH_TRACING_H_

#include <lib/zircon-internal/ktrace.h>

#include <array>
#include <iterator>
#include <map>
#include <string>
#include <vector>

#include "utility.h"

typedef enum { kTag16B, kTag32B, kTagNAME } TagType;

typedef struct {
  uint32_t num;
  uint32_t group;
  TagType type;
  const char* name;
} TagDefinition;

class KTraceRecord {
 public:
  static std::optional<KTraceRecord> ParseRecord(uint8_t* data_buf, size_t buf_len);

  bool Get16BRecord(ktrace_header_t** record) const;
  bool Get32BRecord(ktrace_rec_32b_t** record) const;
  bool GetNameRecord(ktrace_rec_name_t** record) const;
  std::optional<std::array<uint32_t, 2>> Get64BitPayload() const;
  std::optional<std::array<uint64_t, 2>> Get128BitPayload() const;
  std::optional<const uint64_t> GetFlowID() const;
  std::optional<const uint64_t> GetAssociatedThread() const;

  uint32_t GetEvent() const { return event_; }
  TagDefinition* GetInfo() const { return info_; }

  bool IsNamed() const { return is_named_; }
  bool IsProbeGroup() const { return is_probe_group_; }
  bool IsFlow() const { return is_flow_; }
  bool IsBegin() const { return is_begin_; }
  bool IsEnd() const { return is_end_; }
  bool IsCounter() const { return is_counter_; }
  bool IsDuration() const { return is_duration_; }
  bool HasUnexpectedEvent() const { return has_unexpected_event_; }

 private:
  size_t data_buf_len_;
  ktrace_header_t* rec_16b_ = nullptr;
  uint32_t event_;
  TagDefinition* info_;

  bool is_named_ = false;
  bool is_probe_group_ = false;
  bool is_flow_ = false;
  bool is_begin_ = false;
  bool is_end_ = false;
  bool is_counter_ = false;
  bool is_duration_ = false;
  bool has_unexpected_event_ = false;
};

class Tracing {
 public:
  Tracing() { Stop(); }

  Tracing(const Tracing&) = delete;
  Tracing& operator=(const Tracing&) = delete;

  Tracing(Tracing&&) = delete;
  Tracing& operator=(Tracing&&) = delete;

  virtual ~Tracing() { Stop(); }

  struct DurationStats {
    uint64_t begin_ts_ns = 0;
    uint64_t end_ts_ns = 0;
    uint64_t wall_duration_ns = 0;
    std::optional<std::array<uint64_t, 2>> payload = std::nullopt;

    DurationStats(uint64_t begin) { begin_ts_ns = begin; }
  };

  struct QueuingStats {
    uint64_t begin_ts_ns = 0;
    uint64_t end_ts_ns = 0;
    uint64_t queuing_time_ns = 0;
    uint64_t associated_thread = 0;

    QueuingStats(uint64_t begin, uint64_t thread) {
      begin_ts_ns = begin;
      associated_thread = thread;
    }
  };

  // Rewinds kernel trace buffer.
  void Rewind();

  // Starts kernel tracing.
  void Start(uint32_t group_mask);

  // Stops kernel tracing.
  void Stop();

  // Fetches record from kernel buffer if available. Returns false if errors were encountered.
  // Returns two booleans, first signals whether read was successful, second signals whether entire
  // kernel trace buffer has been read.
  virtual std::tuple<bool, bool> FetchRecord(zx_handle_t handle, uint8_t* data_buf,
                                             uint32_t* offset, size_t* bytes_read, size_t buf_len);

  // Reads trace buffer and converts output into human-readable format. Stores in location defined
  // by <filepath>. Will overwrite any existing files with same name.
  bool WriteHumanReadable(std::ostream& filepath);

  // Picks out traces pertaining to name in string_ref and runs stats on them. Returns false if name
  // not found.
  bool PopulateDurationStats(std::string string_ref, std::vector<DurationStats>* duration_stats,
                             std::map<uint64_t, QueuingStats>* queuing_stats);

  bool running() const { return running_; }

 private:
  enum EventState {
    kBegin,
    kEnd,
    kNone,
  };

  // Performs same action as zx_ktrace_read and does necessary checks.
  virtual void ReadKernelBuffer(zx_handle_t handle, void* data_buf, uint32_t offset, size_t len,
                                size_t* bytes_read);

  // Returns a string with human-readable translations of tag name, event, and any possible flags.
  std::string InterpretTag(const uint32_t tag, const TagDefinition& info);

  // Writes human-readable translation for 16 byte records into file specified by <file>.
  void Write16B(const KTraceRecord record, std::ostream* file);

  // Writes human-readable translation for 32 byte records into file specified by <file>.
  void Write32B(const KTraceRecord record, std::ostream* file);

  // Writes human-readable translation name type records into file specified by <file>.
  void WriteName(const KTraceRecord record, std::ostream* file);

  // Writes human-readable translation for probe records into file specified by <file>.
  void WriteProbeRecord(const KTraceRecord record, std::ostream* file);

  // Writes human-readable translation for probe records into file specified by <file>.
  void WriteDurationRecord(const KTraceRecord record, const EventState event_state,
                           std::ostream* file);

  // Writes human-readable translation for flow records into file specified by <file>.
  void WriteFlowRecord(const KTraceRecord record, const EventState event_state, std::ostream* file);

  zx_handle_t debug_resource_ = GetDebugResource()->get();
  bool running_ = false;
};

#endif  // SRC_TESTING_LOADBENCH_TRACING_H_
