// 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 <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_
