// 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/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(); }

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