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

// TODO(dje): The "category" mechanism is limiting but it's what we have
// at the moment.

#ifndef GARNET_BIN_CPUPERF_PROVIDER_CATEGORIES_H_
#define GARNET_BIN_CPUPERF_PROVIDER_CATEGORIES_H_

#include <stddef.h>
#include <stdint.h>

#include <functional>
#include <string>
#include <unordered_set>

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

#include "garnet/lib/perfmon/config.h"
#include "garnet/lib/perfmon/events.h"

namespace cpuperf_provider {

enum class TraceOption {
  // Collect data from the o/s.
  kOs,
  // Collect data from userspace.
  kUser,
  // Collect the PC value for each event that is its own timebase.
  kPc,
  // Collect the set of last branch entries for each event that is its
  // own timebase.
  kLastBranch,
};

enum class CategoryGroup {
  // Options like os vs user.
  kOption,
  // The sampling mode and frequency.
  kSample,
  // Collection of architecturally defined fixed-purpose events.
  kFixedArch,
  // Collection of architecturally defined programmable events.
  kProgrammableArch,
  // Collection of model-specific fixed-purpose events.
  kFixedModel,
  // Collection of model-specific programmable events.
  kProgrammableModel,
};

using CategoryValue = uint32_t;

struct CategorySpec {
  const char* name;
  CategoryGroup group;
  // This is only used by kOption and kSample.
  CategoryValue value;
  size_t count;
  const perfmon::EventId* events;
};

struct TimebaseSpec {
  const char* name;
  const perfmon::EventId event;
};

extern const CategorySpec kCommonCategories[];
extern const size_t kNumCommonCategories;

extern const CategorySpec kTargetCategories[];
extern const size_t kNumTargetCategories;

extern const TimebaseSpec kTimebaseCategories[];
extern const size_t kNumTimebaseCategories;

// A data collection run is called a "trace".
// This records the user-specified configuration of the trace.
class TraceConfig final {
 public:
  using IsCategoryEnabledFunc = std::function<bool(const char* name)>;

  static std::unique_ptr<TraceConfig> Create(perfmon::ModelEventManager* model_event_manager,
                                             IsCategoryEnabledFunc category_is_enabled);

  perfmon::ModelEventManager* model_event_manager() const { return model_event_manager_; }

  bool is_enabled() const { return is_enabled_; }

  bool trace_os() const { return trace_os_; }
  bool trace_user() const { return trace_user_; }
  bool trace_pc() const { return trace_pc_; }
  bool trace_last_branch() const { return trace_last_branch_; }

  uint32_t sample_rate() const { return sample_rate_; }

  perfmon::EventId timebase_event() const { return timebase_event_; }

  // Return true if the configuration has changed.
  bool Changed(const TraceConfig& old) const;

  // Translate our representation of the configuration to the device's.
  bool TranslateToDeviceConfig(perfmon::Config* out_config) const;

  // Return a string representation of the config for error reporting.
  std::string ToString() const;

 private:
  // Keeps track of category data for ProcessCategories.
  struct CategoryData {
    bool have_data_to_collect = false;
    bool have_sample_rate = false;
    bool have_programmable_category = false;
  };

  TraceConfig(perfmon::ModelEventManager* model_event_manager,
              IsCategoryEnabledFunc category_is_enabled);

  bool ProcessAllCategories();
  bool ProcessCategories(const CategorySpec categories[], size_t num_categories,
                         CategoryData* data);

  bool ProcessTimebase();

  // Non-owning.
  perfmon::ModelEventManager* const model_event_manager_;

  const IsCategoryEnabledFunc is_category_enabled_;

  bool is_enabled_ = false;

  bool trace_os_ = false;
  bool trace_user_ = false;
  bool trace_pc_ = false;
  bool trace_last_branch_ = false;
  uint32_t sample_rate_ = 0;
  perfmon::EventId timebase_event_ = perfmon::kEventIdNone;

  // Set of selected fixed + programmable categories.
  std::unordered_set<const CategorySpec*> selected_categories_;
};

}  // namespace cpuperf_provider

#endif  // GARNET_BIN_CPUPERF_PROVIDER_CATEGORIES_H_
