// 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_PROJECT_CONTEXT_H_
#define COBALT_SRC_LOGGER_PROJECT_CONTEXT_H_

#include <map>
#include <memory>
#include <string>
#include <utility>

#include <google/protobuf/repeated_field.h>

#include "src/lib/util/status_builder.h"
#include "src/public/lib/registry_identifiers.h"
#include "src/public/lib/statusor/statusor.h"
#include "src/registry/cobalt_registry.pb.h"
#include "src/registry/metric_definition.pb.h"
#include "src/registry/project.pb.h"
#include "src/registry/project_configs.h"

namespace cobalt::logger {

// A pair (metric ID, report ID).
using MetricReportId = std::pair<uint32_t, uint32_t>;

// A reference object that gives access to the names and IDs of a Metric and
// its owning Project and Customer. One way to obtain a MetricRef is the method
// ProjectContext::RefMetric().
class MetricRef {
 public:
  // A MetricRef is constructed from a Project and a MetricDefinition. The
  // Project and MetricDefinition must remain valid as long as the MetricRef is
  // being used.
  MetricRef(const Project* project, const MetricDefinition* metric_definition);

  [[nodiscard]] const Project& project() const;

  [[nodiscard]] std::string ProjectDebugString() const;

  [[nodiscard]] uint32_t metric_id() const;

  [[nodiscard]] const MetricDefinition* metric_definition() const;

  [[nodiscard]] const std::string& metric_name() const;

  // Returns the string <customer_name>.<project_name>.<metric_name>
  [[nodiscard]] std::string FullyQualifiedName() const;

 private:
  friend class ProjectContext;
  const Project* project_;
  const MetricDefinition* metric_definition_;
};

// ProjectContext stores the metrics registration data for a single Cobalt
// project and makes it conveniently available on the client.
//
// The underlying data comes from a |ProjectConfig| proto message which
// represents a single project within the Cobalt Registry.  An instance of
// ProjectContext does not copy the data from a |ProjectConfig|, but rather
// maintains a pointer to an instance of |ProjectConfig|. An instance of
// ProjectContext may or may not own its underlying |ProjectConfig|, depending
// on which constructor is used.
class ProjectContext {
 public:
  // Constructs an instance of ProjectContext that does own the
  // underlying |ProjectConfig|.
  //
  // |customer_id| The id of the customer this project is for.
  //
  // |customer_name| The name of the customer this project is for.
  //
  // |project_config| The |ProjectConfig| containing the project data.
  ProjectContext(uint32_t customer_id, const std::string& customer_name,
                 std::unique_ptr<ProjectConfig> project_config);

  // Constructs an instance of ProjectContext that does not own the
  // underlying |ProjectConfig|.
  //
  // |customer_id| The id of the customer this project is for.
  //
  // |customer_name| The name of the customer this project is for.
  //
  // |project_config| The |ProjectConfig| containing the project data.
  ProjectContext(uint32_t customer_id, const std::string& customer_name,
                 const ProjectConfig* project_config);

  // Returns the MetricDefinition for the metric with the given name, or
  // nullptr if there is no such metric.
  const MetricDefinition* GetMetric(const std::string& metric_name) const;

  // Returns the MetricDefinition for the metric with the given ID, or
  // nullptr if there is no such metric.
  const MetricDefinition* GetMetric(uint32_t metric_id) const;
  const MetricDefinition* GetMetric(lib::MetricIdentifier metric) const {
    return GetMetric(metric.metric_id());
  }

  // Makes a MetricRef that wraps this ProjectContext's Project and the given
  // metric_definition (which should have been obtained via GetMetric()).
  // The Project and MetricDefinition must remain valid as long as the returned
  // MetricRef is being used.
  MetricRef RefMetric(const MetricDefinition* metric_definition) const;

  // Gives access to the metadata for the project.
  const Project& project() const { return project_; }

  // Gives access to the list of all MetricDefinitions for the project.
  const google::protobuf::RepeatedPtrField<MetricDefinition>& metrics() const {
    return project_config_->metrics();
  }

  std::string DebugString() const;

  // Returns the string <customer_name>(<id>).<project_name>(<id>)
  std::string static FullyQualifiedName(const Project& project);

  // Returns the string
  // <customer_name>(<id>).<project_name>(<id>).<metric_name>(<id>)
  std::string static FullMetricName(const Project& project, const MetricDefinition& metric);

  // Returns the string <customer_name>(<id>).<project_name>(<id>)
  std::string FullyQualifiedName() const;

  // Returns the string
  // <customer_name>(<id>).<project_name>(<id>).<metric_name>(<id>)
  std::string FullMetricName(const MetricDefinition& metric_definition) const;

  // ListMetrics returns a list of metric identifiers that are present in this project.
  std::vector<lib::MetricIdentifier> ListMetrics() const;

  [[nodiscard]] lib::ProjectIdentifier Identifier() const;

 private:
  // Constructs an instance of ProjectContext that may or may not own the
  // underlying |ProjectConfig|.
  //
  // |customer_id| The id of the customer this project is for.
  //
  // |customer_name| The name of the customer this project is for.
  //
  // |owned_project_config| Exactly one of |owned_project_config| or
  // |project_config| must be not null or we will CHECK fail.
  //
  // |project_config| Exactly one of |owned_project_config| or
  // |project_config| must be not null or we will CHECK fail.
  ProjectContext(uint32_t customer_id, const std::string& customer_name,
                 const ProjectConfig* project_config,
                 std::unique_ptr<ProjectConfig> owned_project_config);

  Project project_;

  // This pointer is always non-null and points either to
  // maybe_null_project_config_ or to an instance of ProjectConfig
  // not owned by this object. Access the underlying ProjectConfig through
  // this pointer and never through maybe_null_project_config_;
  const ProjectConfig* project_config_;

  // An instance of ProjectContext may or may not own the underlying
  // ProjectConfig, so this may or may not be null. Never access this
  // variable directly after it is initialized in the constructor. Instead
  // access |project_config_|.
  const std::unique_ptr<ProjectConfig> maybe_null_project_config_;

  std::map<const std::string, const MetricDefinition*> metrics_by_name_;
  std::map<const uint32_t, const MetricDefinition*> metrics_by_id_;
};

}  // namespace cobalt::logger

namespace cobalt::util {

// Specialization of ContextFormatter for logger::MetricRef to give it default formatting and
// allow it to be passed to StatusBuilder::WithContexts.
//
// Will print Metric=<FullyQualifiedName()> by default.
template <>
class ContextFormatter<logger::MetricRef> {
 public:
  explicit ContextFormatter(const logger::MetricRef& v) : v_(v) {}
  inline static std::string default_key() { return "Metric"; }
  inline void write_value(std::ostream& stream) { stream << v_.FullyQualifiedName(); }

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

// Specialization of ContextFormatter for logger::ProjectContext to give it default formatting and
// allow it to be passed to StatusBuilder::WithContexts.
//
// Will print Project=<FullyQualifiedName()> by default.
template <>
class ContextFormatter<logger::ProjectContext> {
 public:
  explicit ContextFormatter(const logger::ProjectContext& v) : v_(v) {}
  static std::string default_key() { return "Project"; }
  void write_value(std::ostream& stream) { stream << v_.FullyQualifiedName(); }

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

}  // namespace cobalt::util

#endif  // COBALT_SRC_LOGGER_PROJECT_CONTEXT_H_
