/*
 *  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.
 */

#include "webrtc/api/stats/rtcstats.h"

#include <sstream>

#include "webrtc/rtc_base/stringencode.h"

namespace webrtc {

namespace {

// Produces "{ a, b, c }". Works for non-vector |RTCStatsMemberInterface::Type|
// types.
template<typename T>
std::string VectorToString(const std::vector<T>& vector) {
  if (vector.empty())
    return "{}";
  std::ostringstream oss;
  oss << "{ " << rtc::ToString<T>(vector[0]);
  for (size_t i = 1; i < vector.size(); ++i) {
    oss << ", " << rtc::ToString<T>(vector[i]);
  }
  oss << " }";
  return oss.str();
}

// Produces "{ \"a\", \"b\", \"c\" }". Works for vectors of both const char* and
// std::string element types.
template<typename T>
std::string VectorOfStringsToString(const std::vector<T>& strings) {
  if (strings.empty())
    return "{}";
  std::ostringstream oss;
  oss << "{ \"" << rtc::ToString<T>(strings[0]) << '\"';
  for (size_t i = 1; i < strings.size(); ++i) {
    oss << ", \"" << rtc::ToString<T>(strings[i]) << '\"';
  }
  oss << " }";
  return oss.str();
}

}  // namespace

bool RTCStats::operator==(const RTCStats& other) const {
  if (type() != other.type() || id() != other.id())
    return false;
  std::vector<const RTCStatsMemberInterface*> members = Members();
  std::vector<const RTCStatsMemberInterface*> other_members = other.Members();
  RTC_DCHECK_EQ(members.size(), other_members.size());
  for (size_t i = 0; i < members.size(); ++i) {
    const RTCStatsMemberInterface* member = members[i];
    const RTCStatsMemberInterface* other_member = other_members[i];
    RTC_DCHECK_EQ(member->type(), other_member->type());
    RTC_DCHECK_EQ(member->name(), other_member->name());
    if (*member != *other_member)
      return false;
  }
  return true;
}

bool RTCStats::operator!=(const RTCStats& other) const {
  return !(*this == other);
}

std::string RTCStats::ToString() const {
  std::ostringstream oss;
  oss << type() << " {\n  id: \"" << id_ << "\"\n  timestamp: "
      << timestamp_us_ << '\n';
  for (const RTCStatsMemberInterface* member : Members()) {
    oss << "  " << member->name() << ": ";
    if (member->is_defined()) {
      if (member->is_string())
        oss << '"' << member->ValueToString() << "\"\n";
      else
        oss << member->ValueToString() << '\n';
    } else {
      oss << "undefined\n";
    }
  }
  oss << '}';
  return oss.str();
}

std::vector<const RTCStatsMemberInterface*> RTCStats::Members() const {
  return MembersOfThisObjectAndAncestors(0);
}

std::vector<const RTCStatsMemberInterface*>
RTCStats::MembersOfThisObjectAndAncestors(
    size_t additional_capacity) const {
  std::vector<const RTCStatsMemberInterface*> members;
  members.reserve(additional_capacity);
  return members;
}

#define WEBRTC_DEFINE_RTCSTATSMEMBER(T, type, is_seq, is_str, to_str)          \
  template<>                                                                   \
  const RTCStatsMemberInterface::Type RTCStatsMember<T>::kType =               \
      RTCStatsMemberInterface::type;                                           \
  template<>                                                                   \
  bool RTCStatsMember<T>::is_sequence() const { return is_seq; }               \
  template<>                                                                   \
  bool RTCStatsMember<T>::is_string() const { return is_str; }                 \
  template<>                                                                   \
  std::string RTCStatsMember<T>::ValueToString() const {                       \
    RTC_DCHECK(is_defined_);                                                   \
    return to_str;                                                             \
  }

WEBRTC_DEFINE_RTCSTATSMEMBER(bool, kBool, false, false,
                             rtc::ToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(int32_t, kInt32, false, false,
                             rtc::ToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(uint32_t, kUint32, false, false,
                             rtc::ToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(int64_t, kInt64, false, false,
                             rtc::ToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(uint64_t, kUint64, false, false,
                             rtc::ToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(double, kDouble, false, false,
                             rtc::ToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(std::string, kString, false, true,
                             value_);
WEBRTC_DEFINE_RTCSTATSMEMBER(
    std::vector<bool>, kSequenceBool, true, false,
    VectorToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(
    std::vector<int32_t>, kSequenceInt32, true, false,
    VectorToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(
    std::vector<uint32_t>, kSequenceUint32, true, false,
    VectorToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(
    std::vector<int64_t>, kSequenceInt64, true, false,
    VectorToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(
    std::vector<uint64_t>, kSequenceUint64, true, false,
    VectorToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(
    std::vector<double>, kSequenceDouble, true, false,
    VectorToString(value_));
WEBRTC_DEFINE_RTCSTATSMEMBER(
    std::vector<std::string>, kSequenceString, true, false,
    VectorOfStringsToString(value_));

}  // namespace webrtc
