// 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 "src/lib/cobalt/cpp/cobalt_event_builder.h"

#include <lib/syslog/cpp/macros.h>

namespace cobalt {

using fuchsia::cobalt::CobaltEvent;
using fuchsia::cobalt::CountEvent;
using fuchsia::cobalt::Event;
using fuchsia::cobalt::HistogramBucket;

CobaltEventBuilder::CobaltEventBuilder(uint32_t metric_id) { event_.metric_id = metric_id; }

CobaltEventBuilder &CobaltEventBuilder::with_event_code(const uint32_t event_code) {
  event_.event_codes.push_back(event_code);
  return *this;
}

CobaltEventBuilder &CobaltEventBuilder::with_event_code_at(const uint32_t index,
                                                           const uint32_t event_code) {
  FX_CHECK(index < 5) << "Invalid index passed to CobaltEventBuilder::with_event_code. Cobalt "
                         "events cannot support more than 5 event_codes.";
  while (event_.event_codes.size() <= index) {
    event_.event_codes.push_back(0);
  }
  event_.event_codes[index] = event_code;
  return *this;
}

CobaltEventBuilder &CobaltEventBuilder::with_event_codes(std::vector<uint32_t> event_codes) {
  event_.event_codes = std::move(event_codes);
  return *this;
}

CobaltEventBuilder &CobaltEventBuilder::with_component(std::string component) {
  event_.component = std::move(component);
  return *this;
}

CobaltEventBuilder CobaltEventBuilder::Clone() const {
  CobaltEventBuilder builder;
  event_.Clone(&builder.event_);
  return builder;
}

CobaltEvent CobaltEventBuilder::as_count_event(const int64_t period_duration_micros,
                                               const int64_t count) {
  CountEvent payload;
  payload.period_duration_micros = period_duration_micros;
  payload.count = count;

  event_.payload.set_event_count(std::move(payload));

  return std::move(event_);
}

CobaltEvent CobaltEventBuilder::as_elapsed_time(const int64_t elapsed_micros) {
  event_.payload.set_elapsed_micros(elapsed_micros);

  return std::move(event_);
}

CobaltEvent CobaltEventBuilder::as_frame_rate(const float fps) {
  event_.payload.set_fps(fps);

  return std::move(event_);
}

CobaltEvent CobaltEventBuilder::as_memory_usage(const int64_t memory_bytes_used) {
  event_.payload.set_memory_bytes_used(memory_bytes_used);

  return std::move(event_);
}

CobaltEvent CobaltEventBuilder::as_int_histogram(std::vector<HistogramBucket> int_histogram) {
  event_.payload.set_int_histogram(std::move(int_histogram));

  return std::move(event_);
}

CobaltEvent CobaltEventBuilder::as_event() {
  event_.payload.set_event(Event());

  return std::move(event_);
}

}  // namespace cobalt
