// 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_LOGGER_PROJECT_CONTEXT_H_
#define COBALT_LOGGER_PROJECT_CONTEXT_H_

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

#include "config/metric_definition.pb.h"
#include "config/project.pb.h"
#include "config/project_configs.h"
#include "logger/status.h"
#include "third_party/statusor/statusor.h"

namespace cobalt {
namespace logger {

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

std::string MetricDebugString(const MetricDefinition& metric);

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

  const Project& project() const;

  std::string ProjectDebugString() const;

  uint32_t metric_id() const;

  const std::string& metric_name() const;

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

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

// ProjectContext stores the Cobalt configuration for a single Cobalt project.
class ProjectContext {
 public:
  ProjectContext(uint32_t customer_id, uint32_t project_id,
                 std::string customer_name, std::string project_name,
                 std::unique_ptr<MetricDefinitions> metric_definitions,
                 ReleaseStage release_stage = GA);

  // ConstructWithProjectConfigs tries to extract a project for the specified
  // customer/project name.
  //
  // If either the customer or the project are not found in the supplied
  // ProjectConfigs, then this will return an INVALID_ARGUMENT error.
  static statusor::StatusOr<std::unique_ptr<ProjectContext>>
  ConstructWithProjectConfigs(
      const std::string& customer_name, const std::string& project_name,
      std::shared_ptr<config::ProjectConfigs> project_configs,
      ReleaseStage release_stage = GA);

  const MetricDefinition* GetMetric(const std::string& metric_name) const;
  const MetricDefinition* GetMetric(const uint32_t metric_id) const;

  // 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.
  const MetricRef RefMetric(const MetricDefinition* metric_definition) const;

  const Project& project() const { return project_; }

  const MetricDefinitions* metric_definitions() const {
    return metric_definitions_.get();
  }

  std::string DebugString() const;

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

 private:
  // This constructor assumes that the specified customer/project is present in
  // the ProjectConfigs (this should be checked by ConstructWithProjcetConfigs).
  // If no such project exists, this will CHECK fail.
  ProjectContext(uint32_t customer_id, uint32_t project_id,
                 const std::string& customer_name,
                 const std::string& project_name,
                 std::shared_ptr<config::ProjectConfigs> project_configs,
                 ReleaseStage release_stage);

  Project project_;

  // Exactly one of metric_definitions_ or project_configs_ will be non-null.
  const std::unique_ptr<MetricDefinitions> metric_definitions_;
  const std::shared_ptr<config::ProjectConfigs> project_configs_;

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

}  // namespace logger
}  // namespace cobalt

#endif  // COBALT_LOGGER_PROJECT_CONTEXT_H_
