/*
 *  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 "api/stats/rtcstats.h"

#include <cmath>
#include <cstring>

#include "rtc_base/checks.h"
#include "rtc_base/gunit.h"
#include "rtc_base/json.h"
#include "stats/test/rtcteststats.h"

namespace webrtc {

namespace {

// JSON stores numbers as floating point numbers with 53 significant bits, which
// amounts to about 15.95 decimal digits. Thus, when comparing large numbers
// processed by JSON, that's all the precision we should expect.
const double JSON_EPSILON = 1e-15;

// We do this since Google Test doesn't support relative error.
// This is computed as follows:
// If |a - b| / |a| < EPS, then |a - b| < |a| * EPS, so |a| * EPS is the
// maximum expected error.
double GetExpectedError(const double expected_value) {
  return JSON_EPSILON * fabs(expected_value);
}

}  // namespace

class RTCChildStats : public RTCStats {
 public:
  WEBRTC_RTCSTATS_DECL();

  RTCChildStats(const std::string& id, int64_t timestamp_us)
      : RTCStats(id, timestamp_us), child_int("childInt") {}

  RTCStatsMember<int32_t> child_int;
};

WEBRTC_RTCSTATS_IMPL(RTCChildStats, RTCStats, "child-stats", &child_int);

class RTCGrandChildStats : public RTCChildStats {
 public:
  WEBRTC_RTCSTATS_DECL();

  RTCGrandChildStats(const std::string& id, int64_t timestamp_us)
      : RTCChildStats(id, timestamp_us), grandchild_int("grandchildInt") {}

  RTCStatsMember<int32_t> grandchild_int;
};

WEBRTC_RTCSTATS_IMPL(RTCGrandChildStats,
                     RTCChildStats,
                     "grandchild-stats",
                     &grandchild_int);

TEST(RTCStatsTest, RTCStatsAndMembers) {
  RTCTestStats stats("testId", 42);
  EXPECT_EQ(stats.id(), "testId");
  EXPECT_EQ(stats.timestamp_us(), static_cast<int64_t>(42));
  std::vector<const RTCStatsMemberInterface*> members = stats.Members();
  EXPECT_EQ(members.size(), static_cast<size_t>(14));
  for (const RTCStatsMemberInterface* member : members) {
    EXPECT_FALSE(member->is_defined());
  }
  stats.m_bool = true;
  stats.m_int32 = 123;
  stats.m_uint32 = 123;
  stats.m_int64 = 123;
  stats.m_uint64 = 123;
  stats.m_double = 123.0;
  stats.m_string = std::string("123");

  std::vector<bool> sequence_bool;
  sequence_bool.push_back(true);
  std::vector<int32_t> sequence_int32;
  sequence_int32.push_back(static_cast<int32_t>(1));
  std::vector<uint32_t> sequence_uint32;
  sequence_uint32.push_back(static_cast<uint32_t>(2));
  std::vector<int64_t> sequence_int64;
  sequence_int64.push_back(static_cast<int64_t>(3));
  std::vector<uint64_t> sequence_uint64;
  sequence_uint64.push_back(static_cast<uint64_t>(4));
  std::vector<double> sequence_double;
  sequence_double.push_back(5.0);
  std::vector<std::string> sequence_string;
  sequence_string.push_back(std::string("six"));

  stats.m_sequence_bool = sequence_bool;
  stats.m_sequence_int32 = sequence_int32;
  stats.m_sequence_uint32 = sequence_uint32;
  EXPECT_FALSE(stats.m_sequence_int64.is_defined());
  stats.m_sequence_int64 = sequence_int64;
  stats.m_sequence_uint64 = sequence_uint64;
  stats.m_sequence_double = sequence_double;
  stats.m_sequence_string = sequence_string;
  for (const RTCStatsMemberInterface* member : members) {
    EXPECT_TRUE(member->is_defined());
  }
  EXPECT_EQ(*stats.m_bool, true);
  EXPECT_EQ(*stats.m_int32, static_cast<int32_t>(123));
  EXPECT_EQ(*stats.m_uint32, static_cast<uint32_t>(123));
  EXPECT_EQ(*stats.m_int64, static_cast<int64_t>(123));
  EXPECT_EQ(*stats.m_uint64, static_cast<uint64_t>(123));
  EXPECT_EQ(*stats.m_double, 123.0);
  EXPECT_EQ(*stats.m_string, std::string("123"));
  EXPECT_EQ(*stats.m_sequence_bool, sequence_bool);
  EXPECT_EQ(*stats.m_sequence_int32, sequence_int32);
  EXPECT_EQ(*stats.m_sequence_uint32, sequence_uint32);
  EXPECT_EQ(*stats.m_sequence_int64, sequence_int64);
  EXPECT_EQ(*stats.m_sequence_uint64, sequence_uint64);
  EXPECT_EQ(*stats.m_sequence_double, sequence_double);
  EXPECT_EQ(*stats.m_sequence_string, sequence_string);

  int32_t numbers[] = {4, 8, 15, 16, 23, 42};
  std::vector<int32_t> numbers_sequence(&numbers[0], &numbers[6]);
  stats.m_sequence_int32->clear();
  stats.m_sequence_int32->insert(stats.m_sequence_int32->end(),
                                 numbers_sequence.begin(),
                                 numbers_sequence.end());
  EXPECT_EQ(*stats.m_sequence_int32, numbers_sequence);
}

TEST(RTCStatsTest, EqualityOperator) {
  RTCTestStats empty_stats("testId", 123);
  EXPECT_EQ(empty_stats, empty_stats);

  RTCTestStats stats_with_all_values = empty_stats;
  stats_with_all_values.m_bool = true;
  stats_with_all_values.m_int32 = 123;
  stats_with_all_values.m_uint32 = 123;
  stats_with_all_values.m_int64 = 123;
  stats_with_all_values.m_uint64 = 123;
  stats_with_all_values.m_double = 123.0;
  stats_with_all_values.m_string = "123";
  stats_with_all_values.m_sequence_bool = std::vector<bool>();
  stats_with_all_values.m_sequence_int32 = std::vector<int32_t>();
  stats_with_all_values.m_sequence_uint32 = std::vector<uint32_t>();
  stats_with_all_values.m_sequence_int64 = std::vector<int64_t>();
  stats_with_all_values.m_sequence_uint64 = std::vector<uint64_t>();
  stats_with_all_values.m_sequence_double = std::vector<double>();
  stats_with_all_values.m_sequence_string = std::vector<std::string>();
  EXPECT_NE(stats_with_all_values, empty_stats);
  EXPECT_EQ(stats_with_all_values, stats_with_all_values);
  EXPECT_NE(stats_with_all_values.m_int32, stats_with_all_values.m_uint32);

  RTCTestStats one_member_different[] = {
      stats_with_all_values, stats_with_all_values, stats_with_all_values,
      stats_with_all_values, stats_with_all_values, stats_with_all_values,
      stats_with_all_values, stats_with_all_values, stats_with_all_values,
      stats_with_all_values, stats_with_all_values, stats_with_all_values,
      stats_with_all_values, stats_with_all_values,
  };
  for (size_t i = 0; i < 14; ++i) {
    EXPECT_EQ(stats_with_all_values, one_member_different[i]);
  }
  one_member_different[0].m_bool = false;
  one_member_different[1].m_int32 = 321;
  one_member_different[2].m_uint32 = 321;
  one_member_different[3].m_int64 = 321;
  one_member_different[4].m_uint64 = 321;
  one_member_different[5].m_double = 321.0;
  one_member_different[6].m_string = "321";
  one_member_different[7].m_sequence_bool->push_back(false);
  one_member_different[8].m_sequence_int32->push_back(321);
  one_member_different[9].m_sequence_uint32->push_back(321);
  one_member_different[10].m_sequence_int64->push_back(321);
  one_member_different[11].m_sequence_uint64->push_back(321);
  one_member_different[12].m_sequence_double->push_back(321.0);
  one_member_different[13].m_sequence_string->push_back("321");
  for (size_t i = 0; i < 14; ++i) {
    EXPECT_NE(stats_with_all_values, one_member_different[i]);
  }

  RTCTestStats empty_stats_different_id("testId2", 123);
  EXPECT_NE(empty_stats, empty_stats_different_id);
  RTCTestStats empty_stats_different_timestamp("testId", 321);
  EXPECT_EQ(empty_stats, empty_stats_different_timestamp);

  RTCChildStats child("childId", 42);
  RTCGrandChildStats grandchild("grandchildId", 42);
  EXPECT_NE(child, grandchild);

  RTCChildStats stats_with_defined_member("leId", 0);
  stats_with_defined_member.child_int = 0;
  RTCChildStats stats_with_undefined_member("leId", 0);
  EXPECT_NE(stats_with_defined_member, stats_with_undefined_member);
  EXPECT_NE(stats_with_undefined_member, stats_with_defined_member);
}

TEST(RTCStatsTest, RTCStatsGrandChild) {
  RTCGrandChildStats stats("grandchild", 0.0);
  stats.child_int = 1;
  stats.grandchild_int = 2;
  int32_t sum = 0;
  for (const RTCStatsMemberInterface* member : stats.Members()) {
    sum += *member->cast_to<const RTCStatsMember<int32_t>>();
  }
  EXPECT_EQ(sum, static_cast<int32_t>(3));

  std::unique_ptr<RTCStats> copy_ptr = stats.copy();
  const RTCGrandChildStats& copy = copy_ptr->cast_to<RTCGrandChildStats>();
  EXPECT_EQ(*copy.child_int, *stats.child_int);
  EXPECT_EQ(*copy.grandchild_int, *stats.grandchild_int);
}

TEST(RTCStatsTest, RTCStatsPrintsValidJson) {
  std::string id = "statsId";
  int timestamp = 42;
  bool m_bool = true;
  int m_int32 = 123;
  int64_t m_int64 = 1234567890123456499L;
  double m_double = 123.4567890123456499;
  std::string m_string = "123";

  std::vector<bool> sequence_bool;
  std::vector<int32_t> sequence_int32;
  sequence_int32.push_back(static_cast<int32_t>(1));
  std::vector<int64_t> sequence_int64;
  sequence_int64.push_back(static_cast<int64_t>(-1234567890123456499L));
  sequence_int64.push_back(static_cast<int64_t>(1));
  sequence_int64.push_back(static_cast<int64_t>(1234567890123456499L));
  std::vector<double> sequence_double;
  sequence_double.push_back(123.4567890123456499);
  sequence_double.push_back(1234567890123.456499);
  std::vector<std::string> sequence_string;
  sequence_string.push_back(std::string("four"));

  RTCTestStats stats(id, timestamp);
  stats.m_bool = m_bool;
  stats.m_int32 = m_int32;
  stats.m_int64 = m_int64;
  stats.m_double = m_double;
  stats.m_string = m_string;
  stats.m_sequence_bool = sequence_bool;
  stats.m_sequence_int32 = sequence_int32;
  stats.m_sequence_int64 = sequence_int64;
  stats.m_sequence_double = sequence_double;
  stats.m_sequence_string = sequence_string;

  Json::Value json_output;
  EXPECT_TRUE(Json::Reader().parse(stats.ToJson(), json_output));

  EXPECT_TRUE(rtc::GetStringFromJsonObject(json_output, "id", &id));
  EXPECT_TRUE(rtc::GetIntFromJsonObject(json_output, "timestamp", &timestamp));
  EXPECT_TRUE(rtc::GetBoolFromJsonObject(json_output, "mBool", &m_bool));
  EXPECT_TRUE(rtc::GetIntFromJsonObject(json_output, "mInt32", &m_int32));
  EXPECT_TRUE(rtc::GetDoubleFromJsonObject(json_output, "mDouble", &m_double));
  EXPECT_TRUE(rtc::GetStringFromJsonObject(json_output, "mString", &m_string));

  Json::Value json_array;

  EXPECT_TRUE(
      rtc::GetValueFromJsonObject(json_output, "mSequenceBool", &json_array));
  EXPECT_TRUE(rtc::JsonArrayToBoolVector(json_array, &sequence_bool));

  EXPECT_TRUE(
      rtc::GetValueFromJsonObject(json_output, "mSequenceInt32", &json_array));
  EXPECT_TRUE(rtc::JsonArrayToIntVector(json_array, &sequence_int32));

  EXPECT_TRUE(
      rtc::GetValueFromJsonObject(json_output, "mSequenceDouble", &json_array));
  EXPECT_TRUE(rtc::JsonArrayToDoubleVector(json_array, &sequence_double));

  EXPECT_TRUE(
      rtc::GetValueFromJsonObject(json_output, "mSequenceString", &json_array));
  EXPECT_TRUE(rtc::JsonArrayToStringVector(json_array, &sequence_string));

  EXPECT_EQ(id, stats.id());
  EXPECT_EQ(timestamp, stats.timestamp_us());
  EXPECT_EQ(m_bool, *stats.m_bool);
  EXPECT_EQ(m_int32, *stats.m_int32);
  EXPECT_EQ(m_string, *stats.m_string);
  EXPECT_EQ(sequence_bool, *stats.m_sequence_bool);
  EXPECT_EQ(sequence_int32, *stats.m_sequence_int32);
  EXPECT_EQ(sequence_string, *stats.m_sequence_string);

  EXPECT_NEAR(m_double, *stats.m_double, GetExpectedError(*stats.m_double));

  EXPECT_EQ(sequence_double.size(), stats.m_sequence_double->size());
  for (size_t i = 0; i < stats.m_sequence_double->size(); ++i) {
    EXPECT_NEAR(sequence_double[i], stats.m_sequence_double->at(i),
                GetExpectedError(stats.m_sequence_double->at(i)));
  }

  // We read mInt64 as double since JSON stores all numbers as doubles, so there
  // is not enough precision to represent large numbers.
  double m_int64_as_double;
  std::vector<double> sequence_int64_as_double;

  EXPECT_TRUE(
      rtc::GetDoubleFromJsonObject(json_output, "mInt64", &m_int64_as_double));

  EXPECT_TRUE(
      rtc::GetValueFromJsonObject(json_output, "mSequenceInt64", &json_array));
  EXPECT_TRUE(
      rtc::JsonArrayToDoubleVector(json_array, &sequence_int64_as_double));

  double stats_m_int64_as_double = static_cast<double>(*stats.m_int64);
  EXPECT_NEAR(m_int64_as_double, stats_m_int64_as_double,
              GetExpectedError(stats_m_int64_as_double));

  EXPECT_EQ(sequence_int64_as_double.size(), stats.m_sequence_int64->size());
  for (size_t i = 0; i < stats.m_sequence_int64->size(); ++i) {
    const double stats_value_as_double =
        static_cast<double>((*stats.m_sequence_int64)[i]);
    EXPECT_NEAR(sequence_int64_as_double[i], stats_value_as_double,
                GetExpectedError(stats_value_as_double));
  }

  // Neither stats.m_uint32 nor stats.m_uint64 are defined, so "mUint64" and
  // "mUint32" should not be part of the generated JSON object.
  int m_uint32;
  int m_uint64;
  EXPECT_FALSE(stats.m_uint32.is_defined());
  EXPECT_FALSE(stats.m_uint64.is_defined());
  EXPECT_FALSE(rtc::GetIntFromJsonObject(json_output, "mUint32", &m_uint32));
  EXPECT_FALSE(rtc::GetIntFromJsonObject(json_output, "mUint64", &m_uint64));

  std::cout << stats.ToJson() << std::endl;
}

TEST(RTCStatsTest, IsStandardized) {
  RTCStatsMember<int32_t> standardized("standardized");
  RTCNonStandardStatsMember<int32_t> unstandardized("unstandardized");
  EXPECT_TRUE(standardized.is_standardized());
  EXPECT_FALSE(unstandardized.is_standardized());
}

// Death tests.
// Disabled on Android because death tests misbehave on Android, see
// base/test/gtest_util.h.
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

TEST(RTCStatsDeathTest, ValueOfUndefinedMember) {
  RTCTestStats stats("testId", 0.0);
  EXPECT_FALSE(stats.m_int32.is_defined());
  EXPECT_DEATH(*stats.m_int32, "");
}

TEST(RTCStatsDeathTest, InvalidCasting) {
  RTCGrandChildStats stats("grandchild", 0.0);
  EXPECT_DEATH(stats.cast_to<RTCChildStats>(), "");
}

#endif  // RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)

}  // namespace webrtc
