// Copyright 2018 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 COBALT_SRC_LOGGER_EVENT_RECORD_H_
#define COBALT_SRC_LOGGER_EVENT_RECORD_H_

#include <memory>

#include <third_party/abseil-cpp/absl/strings/str_cat.h>

#include "src/lib/util/datetime_util.h"
#include "src/lib/util/status_builder.h"
#include "src/logger/project_context.h"
#include "src/logging.h"
#include "src/pb/common.pb.h"
#include "src/pb/event.pb.h"
#include "src/public/lib/registry_identifiers.h"
#include "src/public/lib/statusor/statusor.h"
#include "src/registry/metric_definition.pb.h"

namespace cobalt::logger {

// A container for an Event proto message and the ProjectContext and the metric within it for which
// that Event should be logged.
class EventRecord {
 public:
  static lib::statusor::StatusOr<std::unique_ptr<EventRecord>> MakeEventRecord(
      std::shared_ptr<const ProjectContext> project_context, uint32_t metric_id) {
    std::unique_ptr<EventRecord> record(new EventRecord(std::move(project_context), metric_id));

    if (record->metric_) {
      return record;
    }

    return Status(StatusCode::INVALID_ARGUMENT, "Provided metric_id (" + std::to_string(metric_id) +
                                                    ") does not match a known metric");
  }
  ~EventRecord() = default;
  EventRecord(EventRecord&& rhs) = default;

  // Get the ProjectContext associated with this Event.
  [[nodiscard]] const ProjectContext* project_context() const { return project_context_.get(); }

  // Get the Metric within the ProjectContext that this Event is for.
  [[nodiscard]] const MetricDefinition* metric() const { return metric_; }

  // Get the Event that is to be logged.
  [[nodiscard]] Event* event() const { return event_.get(); }

  [[nodiscard]] util::TimeInfo GetTimeInfo() const {
    return {
        .day_index = event_->day_index(),
        .hour_id = event_->hour_id(),
    };
  }

  // Get the SystemProfile that is to be logged with the event. Only used for Cobalt 1.1 metrics.
  [[nodiscard]] SystemProfile* system_profile() const { return system_profile_.get(); }

  [[nodiscard]] std::string GetLogDetails() const {
    return absl::StrCat("project_id:", metric_->project_id(), " metric_id:", metric_->id());
  }

  [[nodiscard]] std::string FullMetricName() const {
    return project_context_->FullMetricName(*metric_);
  }

  [[nodiscard]] lib::MetricIdentifier MetricIdentifier() const {
    return project_context_->Identifier().ForMetric(metric_->id());
  }

 private:
  EventRecord(std::shared_ptr<const ProjectContext> project_context, uint32_t metric_id)
      : project_context_(std::move(project_context)),
        event_(std::make_unique<Event>()),
        system_profile_(std::make_unique<SystemProfile>()) {
    metric_ = project_context_->GetMetric(metric_id);
  }

  const std::shared_ptr<const ProjectContext> project_context_;
  const MetricDefinition* metric_;
  std::unique_ptr<Event> event_;
  std::unique_ptr<SystemProfile> system_profile_;
};

}  // namespace cobalt::logger

namespace cobalt::util {

// Specialization of ContextFormatter for logger::EventRecord to give it default formatting and
// allow it to be passed to StatusBuilder::WithContexts.
//
// Will print by default:
//  - With no metric: Project=<project_context()->FullyQualifiedName()>
//  - With a metric: Metric=<FullMetricName()>
template <>
class ContextFormatter<logger::EventRecord> {
 public:
  explicit ContextFormatter(const logger::EventRecord& v) : v_(v) {}
  std::string default_key() {
    if (v_.metric()) {
      return "Metric";
    }
    return "Project";
  }
  void write_value(std::ostream& stream) {
    if (v_.metric()) {
      stream << v_.FullMetricName();
    } else {
      stream << v_.project_context()->FullyQualifiedName();
    }
  }

 private:
  const logger::EventRecord& v_;
};

}  // namespace cobalt::util

#endif  // COBALT_SRC_LOGGER_EVENT_RECORD_H_
