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

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

#include <src/lib/fxl/logging.h>
#include <src/lib/fxl/strings/string_printf.h>

namespace perfmon {

std::string Config::StatusToString(Status status) {
  switch (status) {
  case Status::OK:
    return "OK";
  case Status::MAX_EVENTS:
    return "MAX_EVENTS";
  case Status::INVALID_ARGS:
    return "INVALID_ARGS";
  }
}

void Config::Reset() {
  events_.clear();
}

Config::Status Config::AddEvent(
    EventId event, EventRate rate, uint32_t flags) {
  if (events_.size() == kMaxNumEvents) {
    return Status::MAX_EVENTS;
  }
  if (rate == 0 && (flags & Config::kNonZeroRateOnlyFlags) != 0) {
    return Status::INVALID_ARGS;
  }
  events_.emplace(EventConfig{event, rate, flags});
  return Status::OK;
}

size_t Config::GetEventCount() const {
  return events_.size();
}

CollectionMode Config::GetMode() const {
  for (const auto& event : events_) {
    // If any event is doing sampling, then we're in "sample mode".
    if (event.rate != 0) {
      return CollectionMode::kSample;
    }
  }
  return CollectionMode::kTally;
}

void Config::IterateOverEvents(IterateFunc func) const {
  for (const auto& event : events_) {
    func(event);
  }
}

static std::string EventConfigToString(Config::EventConfig event) {
  return fxl::StringPrintf("event 0x%x, rate %u, flags 0x%x",
                           event.event, event.rate, event.flags);
}

std::string Config::ToString() {
  std::string result;
  for (const auto& event : events_) {
    if (!result.empty()) {
      result += "; ";
    }
    result += EventConfigToString(event);
  }
  return result;
}

static void ToIoctlEvent(const Config::EventConfig& event, size_t index,
                         perfmon_ioctl_config_t* out_config) {
  out_config->events[index].event = event.event;
  out_config->events[index].rate = event.rate;
  if (event.flags & Config::kFlagOs) {
    out_config->events[index].flags |= PERFMON_CONFIG_FLAG_OS;
  }
  if (event.flags & Config::kFlagUser) {
    out_config->events[index].flags |= PERFMON_CONFIG_FLAG_USER;
  }
  if (event.flags & Config::kFlagPc) {
    out_config->events[index].flags |= PERFMON_CONFIG_FLAG_PC;
  }
  if (event.flags & Config::kFlagTimebase) {
    out_config->events[index].flags |= PERFMON_CONFIG_FLAG_TIMEBASE;
  }
  if (event.flags & Config::kFlagLastBranch) {
    out_config->events[index].flags |= PERFMON_CONFIG_FLAG_LAST_BRANCH;
  }
}

namespace internal {

void PerfmonToIoctlConfig(const Config& config,
                          perfmon_ioctl_config_t* out_config) {
  *out_config = {};
  FXL_DCHECK(config.GetEventCount() <= kMaxNumEvents);

  size_t i = 0;

  config.IterateOverEvents([&](const Config::EventConfig& event) {
    ToIoctlEvent(event, i, out_config);
    ++i;
  });
}

}  // namespace internal

}  // namespace perfmon
