/*
 *  Copyright 2016 The WebRTC Project Authors. All rights reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#ifndef API_STATS_RTC_STATS_H_
#define API_STATS_RTC_STATS_H_

#include <stddef.h>
#include <stdint.h>

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

#include "api/stats/attribute.h"
#include "api/units/timestamp.h"
#include "rtc_base/checks.h"
#include "rtc_base/system/rtc_export.h"
#include "rtc_base/system/rtc_export_template.h"

namespace webrtc {

// Abstract base class for RTCStats-derived dictionaries, see
// https://w3c.github.io/webrtc-stats/.
//
// All derived classes must have the following static variable defined:
//   static const char kType[];
// It is used as a unique class identifier and a string representation of the
// class type, see https://w3c.github.io/webrtc-stats/#rtcstatstype-str*.
// Use the `WEBRTC_RTCSTATS_IMPL` macro when implementing subclasses, see macro
// for details.
//
// Derived classes list their dictionary attributes, std::optional<T>, as
// public fields, allowing the following:
//
// RTCFooStats foo("fooId", Timestamp::Micros(GetCurrentTime()));
// foo.bar = 42;
// foo.baz = std::vector<std::string>();
// foo.baz->push_back("hello world");
// uint32_t x = *foo.bar;
//
// Pointers to all the attributes are available with `Attributes()`, allowing
// iteration:
//
// for (const auto& attribute : foo.Attributes()) {
//   printf("%s = %s\n", attribute.name(), attribute.ToString().c_str());
// }
class RTC_EXPORT RTCStats {
 public:
  RTCStats(const std::string& id, Timestamp timestamp)
      : id_(id), timestamp_(timestamp) {}
  RTCStats(const RTCStats& other);
  virtual ~RTCStats();

  virtual std::unique_ptr<RTCStats> copy() const = 0;

  const std::string& id() const { return id_; }
  // Time relative to the UNIX epoch (Jan 1, 1970, UTC), in microseconds.
  Timestamp timestamp() const { return timestamp_; }

  // Returns the static member variable `kType` of the implementing class.
  virtual const char* type() const = 0;
  // Returns all attributes of this stats object, i.e. a list of its individual
  // metrics as viewed via the Attribute wrapper.
  std::vector<Attribute> Attributes() const;
  template <typename T>
  Attribute GetAttribute(const std::optional<T>& stat) const {
    for (const auto& attribute : Attributes()) {
      if (!attribute.holds_alternative<T>()) {
        continue;
      }
      if (absl::get<const std::optional<T>*>(attribute.as_variant()) == &stat) {
        return attribute;
      }
    }
    RTC_CHECK_NOTREACHED();
  }
  // Checks if the two stats objects are of the same type and have the same
  // attribute values. Timestamps are not compared. These operators are exposed
  // for testing.
  bool operator==(const RTCStats& other) const;
  bool operator!=(const RTCStats& other) const;

  // Creates a JSON readable string representation of the stats
  // object, listing all of its attributes (names and values).
  std::string ToJson() const;

  // Downcasts the stats object to an `RTCStats` subclass `T`. DCHECKs that the
  // object is of type `T`.
  template <typename T>
  const T& cast_to() const {
    RTC_DCHECK_EQ(type(), T::kType);
    return static_cast<const T&>(*this);
  }

 protected:
  virtual std::vector<Attribute> AttributesImpl(
      size_t additional_capacity) const;

  std::string const id_;
  Timestamp timestamp_;
};

// All `RTCStats` classes should use these macros.
// `WEBRTC_RTCSTATS_DECL` is placed in a public section of the class definition.
// `WEBRTC_RTCSTATS_IMPL` is placed outside the class definition (in a .cc).
//
// These macros declare (in _DECL) and define (in _IMPL) the static `kType` and
// overrides methods as required by subclasses of `RTCStats`: `copy`, `type` and
// `AttributesImpl`. The |...| argument is a list of addresses to each attribute
// defined in the implementing class. The list must have at least one attribute.
//
// (Since class names need to be known to implement these methods this cannot be
// part of the base `RTCStats`. While these methods could be implemented using
// templates, that would only work for immediate subclasses. Subclasses of
// subclasses also have to override these methods, resulting in boilerplate
// code. Using a macro avoids this and works for any `RTCStats` class, including
// grandchildren.)
//
// Sample usage:
//
// rtcfoostats.h:
//   class RTCFooStats : public RTCStats {
//    public:
//     WEBRTC_RTCSTATS_DECL();
//
//     RTCFooStats(const std::string& id, Timestamp timestamp);
//
//     std::optional<int32_t> foo;
//     std::optional<int32_t> bar;
//   };
//
// rtcfoostats.cc:
//   WEBRTC_RTCSTATS_IMPL(RTCFooStats, RTCStats, "foo-stats"
//       &foo,
//       &bar);
//
//   RTCFooStats::RTCFooStats(const std::string& id, Timestamp timestamp)
//       : RTCStats(id, timestamp),
//         foo("foo"),
//         bar("bar") {
//   }
//
#define WEBRTC_RTCSTATS_DECL()                                              \
 protected:                                                                 \
  std::vector<webrtc::Attribute> AttributesImpl(size_t additional_capacity) \
      const override;                                                       \
                                                                            \
 public:                                                                    \
  static const char kType[];                                                \
                                                                            \
  std::unique_ptr<webrtc::RTCStats> copy() const override;                  \
  const char* type() const override

#define WEBRTC_RTCSTATS_IMPL(this_class, parent_class, type_str, ...)         \
  const char this_class::kType[] = type_str;                                  \
                                                                              \
  std::unique_ptr<webrtc::RTCStats> this_class::copy() const {                \
    return std::make_unique<this_class>(*this);                               \
  }                                                                           \
                                                                              \
  const char* this_class::type() const {                                      \
    return this_class::kType;                                                 \
  }                                                                           \
                                                                              \
  std::vector<webrtc::Attribute> this_class::AttributesImpl(                  \
      size_t additional_capacity) const {                                     \
    webrtc::AttributeInit attribute_inits[] = {__VA_ARGS__};                  \
    size_t attribute_inits_size =                                             \
        sizeof(attribute_inits) / sizeof(attribute_inits[0]);                 \
    std::vector<webrtc::Attribute> attributes = parent_class::AttributesImpl( \
        attribute_inits_size + additional_capacity);                          \
    for (size_t i = 0; i < attribute_inits_size; ++i) {                       \
      attributes.push_back(absl::visit(                                       \
          [&](const auto* field) {                                            \
            return Attribute(attribute_inits[i].name, field);                 \
          },                                                                  \
          attribute_inits[i].variant));                                       \
    }                                                                         \
    return attributes;                                                        \
  }

}  // namespace webrtc

#endif  // API_STATS_RTC_STATS_H_
