// 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_PERFMON_BUFFER_READER_H_
#define GARNET_LIB_PERFMON_BUFFER_READER_H_

#include <lib/zircon-internal/device/cpu-trace/perf-mon.h>
#include <zircon/types.h>

#include <cstdint>
#include <memory>
#include <string>

#include "records.h"
#include "src/lib/fxl/macros.h"
#include "types.h"

namespace perfmon {

// This class provides support for reading one in-memory buffer of data.

class BufferReader {
 public:
  // |buffer| must be sufficiently aligned (uin64_t).
  static ReaderStatus Create(const std::string& name, const void* buffer, size_t buffer_size,
                             std::unique_ptr<BufferReader>* out_reader);

  static ReaderStatus AnalyzeHeader(const BufferHeader* header, size_t buffer_size);

  ReaderStatus status() const { return status_; }

  // The returned value is zero until the first call to ReadNextRecord(),
  // after which it contains the value used by the trace.
  // Note: The returned value could be bogus, including zero.
  // We just pass on what the trace told us.
  uint64_t ticks_per_second() const { return ticks_per_second_; }

  // Return the current time, in ticks, based on the last time record read.
  // It is assumed that ReadNextRecord has been called at least once.
  // Returns zero if not.
  zx_time_t time() const { return time_; }

  // Return a pointer to the buffer we're reading.
  const void* buffer() const { return buffer_; }

  // Return the total number of bytes captured.
  size_t captured_bytes() const { return buffer_end_ - buffer_; }

  // Return the number of remaining bytes to be read.
  size_t remaining_bytes() const { return buffer_end_ - next_record_; }

  // Return the offset of the last record read, for error reporting purposes.
  // Only valid after a call to |ReadNextRecord()|.
  size_t last_record_offset() const { return last_record_ - buffer_; }

  // Read the next record.
  // Note: To avoid unnecessary copying of larger records, the result contains
  // a pointer to the record. Such pointers remain valid until the next call.
  // Returns true on success, false if there are no more records.
  // If an error is encountered during reading an error is logged and
  // false is returned.
  ReaderStatus ReadNextRecord(SampleRecord* record);

 private:
  // |buffer| must be sufficiently aligned (uin64_t).
  BufferReader(const std::string& name, const void* buffer, size_t capture_end);

  // Utility to update |status_| and return the current value.
  // The status is updated only if it is currently |kOk|.
  ReaderStatus set_status(ReaderStatus status) {
    if (status_ == ReaderStatus::kOk)
      status_ = status;
    return status_;
  }

  // The name of the buffer, used for logging/error reporting.
  const std::string name_;
  const uint8_t* const buffer_;

  const BufferHeader* const header_;
  const uint8_t* next_record_ = nullptr;
  const uint8_t* last_record_ = nullptr;
  const uint8_t* buffer_end_ = nullptr;

  // Reading of one trace can span multiple cpus, and the ticks-per-second
  // value comes from each cpu's trace. Generally it's all the same value,
  // but there is no uber record to specify that. zx_ticks_per_second() will
  // return a constant value (though not necessarily the same value on each
  // boot), and it's this value we expect in the trace. OTOH, we use what
  // the trace buffer gives us. We don't want each record to encode its own
  // value, so keep track of the value here.
  uint64_t ticks_per_second_;

  // The time from the last PERFMON_RECORD_TIME record read.
  zx_time_t time_ = 0;

  // Reader status. Once we get a reader error, reading stops.
  ReaderStatus status_ = ReaderStatus::kOk;

  FXL_DISALLOW_COPY_AND_ASSIGN(BufferReader);
};

}  // namespace perfmon

#endif  // GARNET_LIB_PERFMON_BUFFER_READER_H_
