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

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) {
  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_string_event(std::string string_event) {
  event_.payload.set_string_event(std::move(string_event));

  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
