// Copyright 2021 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_LIB_UTIL_STATUS_BUILDER_H_
#define COBALT_SRC_LIB_UTIL_STATUS_BUILDER_H_

#include <string>

#include "src/lib/util/source_location.h"
#include "src/pb/event.pb.h"
#include "src/public/lib/status.h"
#include "src/public/lib/status_codes.h"
#include "src/registry/metric_definition.pb.h"
#include "src/registry/report_definition.pb.h"

namespace cobalt::util {

// virtual base ContextFormatter, that will be specialized for various types.
// If there is no specialized implementation for a given type, a custom formatter isn't present, and
// can't be used as an argument to WithContexts.
template <typename T>
class ContextFormatter {
  virtual ~ContextFormatter() = default;

  // Return the default key to use if passed to WithContexts (should be inline and static if
  // possible)
  virtual std::string default_key() = 0;

  // Write the value to the given ostream (should be inline)
  virtual void write_value(std::ostream& stream) = 0;
};

class [[nodiscard]] StatusBuilder {
 public:
  explicit StatusBuilder() = delete;
  ~StatusBuilder() = default;

  // Create a StatusBuilder based on |original_status|. Used to add extra contextual information to
  // the status.
  explicit StatusBuilder(const Status& original_status,
                         util::SourceLocation location = util::SourceLocation::current());

  // Create a StatusBuilder for a given |status_code|.
  explicit StatusBuilder(StatusCode status_code,
                         util::SourceLocation location = util::SourceLocation::current());

  // Create a StatusBuilder for a given |status_code| with an |initial message|.
  StatusBuilder(StatusCode status_code, const std::string& initial_message,
                util::SourceLocation location = util::SourceLocation::current());

  // Make StatusBuilder move-only.
  StatusBuilder(const StatusBuilder& sb) = delete;
  StatusBuilder& operator=(const StatusBuilder& sb) = delete;
  StatusBuilder(StatusBuilder&&) = default;
  StatusBuilder& operator=(StatusBuilder&&) = default;

  // Converts the |StatusBuilder| into a |Status| object.
  Status Build();

  StatusBuilder& SetCode(StatusCode status_code) & {
    code_ = status_code;
    return *this;
  }
  // "Owned" (rvalue) version of SetCode that doesn}'t convert StatusBuilder into a reference
  // (lvalue)
  [[nodiscard]] StatusBuilder&& SetCode(StatusCode status_code) && {
    return std::move(SetCode(status_code));
  }

  // LogLevel is used to denote where the status should be logged on construction.
  enum class LogLevel {
    INFO,
    WARNING,
    ERROR,
    NO_LOGGING,
  };

  // These methods define where the status should be logged on construction. If
  // none of these methods are called, or |LogLevel::NO_LOGGING| is provided to
  // the |Log| method, nothing will be logged when the |StatusBuilder| is
  // converted into a |Status|.
  StatusBuilder& Log(LogLevel level) & {
    log_level_ = level;
    return *this;
  }
  // "Owned" (rvalue) version of Log that does not convert StatusBuilder to a reference (lvalue)
  [[nodiscard]] StatusBuilder&& Log(LogLevel level) && { return std::move(Log(level)); }

  // When the |Status| object is created, send it to LOG(ERROR).
  StatusBuilder& LogError() & { return Log(LogLevel::ERROR); }
  // "Owned" (rvalue) version of LogError that does not convert StatusBuilder to a reference
  // (lvalue)
  [[nodiscard]] StatusBuilder&& LogError() && { return std::move(LogError()); }

  // When the |Status| object is created, send it to LOG(WARNING)
  StatusBuilder& LogWarning() & { return Log(LogLevel::WARNING); }
  // "Owned" (rvalue) version of LogWarning that does not convert StatusBuilder to a reference
  // (lvalue)
  [[nodiscard]] StatusBuilder&& LogWarning() && { return std::move(LogWarning()); }

  // When the |Status| object is created, send it to LOG(INFO)
  StatusBuilder& LogInfo() & { return Log(LogLevel::INFO); }
  // "Owned" (rvalue) version of LogInfo that does not convert StatusBuilder to a reference (lvalue)
  [[nodiscard]] StatusBuilder&& LogInfo() && { return std::move(LogInfo()); }

  // WithContext can be used to easily add contextual information to a Status
  // while maintaining the error_code, and error_message.
  //
  // Example:
  //   Status result = DoSomething();
  //   if (!status.ok()) {
  //     // This will add 'Metric=<metric_id>' to the error_details string.
  //     return util::StatusBuilder(result).WithContext("Metric", metric_id);
  //   }
  template <typename V>
  inline StatusBuilder& WithContext(const std::string& key, const V& value) & {
    // Check if stream is empty.
    if (error_details_.tellp() != std::streampos(0)) {
      error_details_ << ", ";
    }
    error_details_ << key << "=";
    if constexpr (std::is_constructible<ContextFormatter<V>, V>::value) {
      // Use the custom ContextFormatter for the value.
      ContextFormatter<V>(value).write_value(error_details_);
    } else {
      error_details_ << value;
    }
    return *this;
  }
  // "Owned" (rvalue) version of WithContext that doesn't convert the StatusBuilder into a reference
  // (lvalue).
  template <typename V>
  inline StatusBuilder&& WithContext(const std::string& key, const V& value) && {
    return std::move(WithContext(key, value));
  }

  // Single argument version of WithContext for types where there is a ContextFormatter defined.
  template <typename V>
  inline StatusBuilder& WithContexts(const V& v) & {
    static_assert(std::is_constructible<ContextFormatter<V>, V>::value,
                  "All arguments to StatusBuilder::WithContext *must* have a ContextFormatter "
                  "implementation");
    return WithContext(ContextFormatter<V>(v).default_key(), v);
  }
  // "Owned" (rvalue) version of the above method that doesn't convert StatusBuilder into reference
  // (lvalue).
  template <typename V>
  inline StatusBuilder&& WithContexts(const V& v) && {
    return std::move(WithContexts(v));
  }

  // Variadic version of WithContexts.
  template <typename V, typename... ContextValues>
  inline StatusBuilder& WithContexts(const V& v, ContextValues&&... args) & {
    WithContexts(v);
    return WithContexts(std::forward<ContextValues>(args)...);
  }
  // "Owned" (rvalue) version of the above method that doesn't convert StatusBuilder into reference
  // (lvalue).
  template <typename V, typename... ContextValues>
  inline StatusBuilder&& WithContexts(const V& v, ContextValues&&... args) && {
    return std::move(WithContexts(v, std::forward<ContextValues>(args)...));
  }

  // AppendMsg appends the value to the error_message;
  template <typename V>
  inline StatusBuilder& AppendMsg(const V& value) & {
    if constexpr (std::is_constructible<ContextFormatter<V>, V>::value) {
      // Use the custom ContextFormatter for the value.
      ContextFormatter<V>(value).write_value(error_message_);
    } else {
      error_message_ << value;
    }
    return *this;
  }

  // "Owned" (rvalue) version of AppendMsg that doesn't convert the StatusBuilder into a reference
  // (lvalue).
  template <typename V>
  [[nodiscard]] inline StatusBuilder&& AppendMsg(const V& value) && {
    return std::move(AppendMsg(value));
  }

 private:
  util::SourceLocation location_;
  StatusCode code_ = StatusCode::OK;
  LogLevel log_level_ = LogLevel::NO_LOGGING;
  std::stringstream error_message_;
  std::stringstream error_details_;
};

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

 private:
  const ReportDefinition& v_;
};

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

 private:
  const MetricDefinition& v_;
};

// Specialization of ContextFormatter for protobuf enums to give them default formatting and allow
// it to be passed to StatusBuilder::WithContexts.
//
// Will print <enum_type>=<enum_string_value> by default.
#define PB_ENUM_FORMATTER(ty)                                                  \
  template <>                                                                  \
  class ContextFormatter<ty> {                                                 \
   public:                                                                     \
    explicit ContextFormatter(const ty& v) : v_(v) {}                          \
    inline static std::string default_key() { return #ty; }                    \
    inline void write_value(std::ostream& stream) { stream << ty##_Name(v_); } \
                                                                               \
   private:                                                                    \
    const ty& v_;                                                              \
  }

PB_ENUM_FORMATTER(MetricDefinition::MetricType);
PB_ENUM_FORMATTER(ReportDefinition::OnDeviceAggregationType);
PB_ENUM_FORMATTER(ReportDefinition::ReportType);

#undef PB_ENUM_FORMATTER

// Specialization of ContextFormatter for Event::TypeCase to give it default formatting and allow it
// to be passed to StatusBuilder::WithContexts.
//
// Will print Event::TypeCase=<v()> by default. Where v() maps to a human-readable string.
template <>
class ContextFormatter<Event::TypeCase> {
 public:
  explicit ContextFormatter(const Event::TypeCase& v) : v_(v) {}
  inline static std::string default_key() { return "Event::TypeCase"; }
  std::string v() {
    switch (v_) {
      case Event::kEventOccurredEvent:
        return "EVENT_OCCURRED";
      case Event::kEventCountEvent:
        return "EVENT_COUNT";
      case Event::kElapsedTimeEvent:
        return "ELAPSED_TIME";
      case Event::kFrameRateEvent:
        return "FRAME_RATE";
      case Event::kMemoryUsageEvent:
        return "MEMORY_USAGE";
      case Event::kIntHistogramEvent:
        return "INT_HISTOGRAM";
      case Event::kOccurrenceEvent:
        return "OCCURRENCE";
      case Event::kIntegerEvent:
        return "INTEGER";
      case Event::kIntegerHistogramEvent:
        return "INTEGER_HISTOGRAM";
      case Event::kStringEvent:
        return "STRING";
      case Event::kCustomEvent:
        return "CUSTOM";
      default:
        return "UNKNOWN_CASE";
    }
  }
  inline void write_value(std::ostream& stream) { stream << v(); }

 private:
  const Event::TypeCase& v_;
};

}  // namespace cobalt::util

#endif  // COBALT_SRC_LIB_UTIL_STATUS_BUILDER_H_
