/*
 *  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 <string>
#include <utility>
#include <vector>

#include "absl/types/optional.h"
#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, absl::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 absl::optional<T>& stat) const {
    for (const auto& attribute : Attributes()) {
      if (!attribute.holds_alternative<T>()) {
        continue;
      }
      if (absl::get<const absl::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);
//
//     absl::optional<int32_t> foo;
//     absl::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_
