/*
 *  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/rtc_stats_report.h"

#include "api/stats/rtc_stats.h"
#include "rtc_base/checks.h"
#include "test/gtest.h"

namespace webrtc {

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

  RTCTestStats1(const std::string& id, Timestamp timestamp)
      : RTCStats(id, timestamp), integer("integer") {}

  RTCStatsMember<int32_t> integer;
};

WEBRTC_RTCSTATS_IMPL(RTCTestStats1, RTCStats, "test-stats-1", &integer)

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

  RTCTestStats2(const std::string& id, Timestamp timestamp)
      : RTCStats(id, timestamp), number("number") {}

  RTCStatsMember<double> number;
};

WEBRTC_RTCSTATS_IMPL(RTCTestStats2, RTCStats, "test-stats-2", &number)

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

  RTCTestStats3(const std::string& id, Timestamp timestamp)
      : RTCStats(id, timestamp), string("string") {}

  RTCStatsMember<std::string> string;
};

WEBRTC_RTCSTATS_IMPL(RTCTestStats3, RTCStats, "test-stats-3", &string)

TEST(RTCStatsReport, AddAndGetStats) {
  rtc::scoped_refptr<RTCStatsReport> report =
      RTCStatsReport::Create(Timestamp::Micros(1337));
  EXPECT_EQ(report->timestamp_us(), 1337u);
  EXPECT_EQ(report->timestamp().us_or(-1), 1337u);
  EXPECT_EQ(report->size(), static_cast<size_t>(0));
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("a0", Timestamp::Micros(1))));
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("a1", Timestamp::Micros(2))));
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats2("b0", Timestamp::Micros(4))));
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats2("b1", Timestamp::Micros(8))));
  report->AddStats(std::unique_ptr<RTCStats>(
      new RTCTestStats1("a2", Timestamp::Micros(16))));
  report->AddStats(std::unique_ptr<RTCStats>(
      new RTCTestStats2("b2", Timestamp::Micros(32))));
  EXPECT_EQ(report->size(), static_cast<size_t>(6));

  EXPECT_EQ(report->Get("missing"), nullptr);
  EXPECT_EQ(report->Get("a0")->id(), "a0");
  EXPECT_EQ(report->Get("b2")->id(), "b2");

  std::vector<const RTCTestStats1*> a = report->GetStatsOfType<RTCTestStats1>();
  EXPECT_EQ(a.size(), static_cast<size_t>(3));
  int64_t mask = 0;
  for (const RTCTestStats1* stats : a)
    mask |= stats->timestamp().us();
  EXPECT_EQ(mask, static_cast<int64_t>(1 | 2 | 16));

  std::vector<const RTCTestStats2*> b = report->GetStatsOfType<RTCTestStats2>();
  EXPECT_EQ(b.size(), static_cast<size_t>(3));
  mask = 0;
  for (const RTCTestStats2* stats : b)
    mask |= stats->timestamp().us();
  EXPECT_EQ(mask, static_cast<int64_t>(4 | 8 | 32));

  EXPECT_EQ(report->GetStatsOfType<RTCTestStats3>().size(),
            static_cast<size_t>(0));
}

TEST(RTCStatsReport, StatsOrder) {
  rtc::scoped_refptr<RTCStatsReport> report =
      RTCStatsReport::Create(Timestamp::Micros(1337));
  EXPECT_EQ(report->timestamp().us(), 1337u);
  EXPECT_EQ(report->timestamp().us_or(-1), 1337u);
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("C", Timestamp::Micros(2))));
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("D", Timestamp::Micros(3))));
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats2("B", Timestamp::Micros(1))));
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats2("A", Timestamp::Micros(0))));
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats2("E", Timestamp::Micros(4))));
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats2("F", Timestamp::Micros(5))));
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats2("G", Timestamp::Micros(6))));
  int64_t i = 0;
  for (const RTCStats& stats : *report) {
    EXPECT_EQ(stats.timestamp().us(), i);
    ++i;
  }
  EXPECT_EQ(i, static_cast<int64_t>(7));
}

TEST(RTCStatsReport, Take) {
  rtc::scoped_refptr<RTCStatsReport> report =
      RTCStatsReport::Create(Timestamp::Zero());
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("A", Timestamp::Micros(1))));
  report->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("B", Timestamp::Micros(2))));
  EXPECT_TRUE(report->Get("A"));
  EXPECT_EQ(report->size(), 2u);
  auto a = report->Take("A");
  EXPECT_TRUE(a);
  EXPECT_EQ(report->size(), 1u);
  EXPECT_FALSE(report->Get("A"));
  EXPECT_FALSE(report->Take("A"));
}

TEST(RTCStatsReport, TakeMembersFrom) {
  rtc::scoped_refptr<RTCStatsReport> a =
      RTCStatsReport::Create(Timestamp::Micros(1337));
  EXPECT_EQ(a->timestamp().us(), 1337u);
  EXPECT_EQ(a->timestamp().us_or(-1), 1337u);
  a->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("B", Timestamp::Micros(1))));
  a->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("C", Timestamp::Micros(2))));
  a->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("E", Timestamp::Micros(4))));
  rtc::scoped_refptr<RTCStatsReport> b =
      RTCStatsReport::Create(Timestamp::Micros(1338));
  EXPECT_EQ(b->timestamp_us(), 1338u);
  EXPECT_EQ(b->timestamp().us_or(-1), 1338u);
  b->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("A", Timestamp::Micros(0))));
  b->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("D", Timestamp::Micros(3))));
  b->AddStats(
      std::unique_ptr<RTCStats>(new RTCTestStats1("F", Timestamp::Micros(5))));

  a->TakeMembersFrom(b);
  EXPECT_EQ(b->size(), static_cast<size_t>(0));
  int64_t i = 0;
  for (const RTCStats& stats : *a) {
    EXPECT_EQ(stats.timestamp().us(), i);
    ++i;
  }
  EXPECT_EQ(i, static_cast<int64_t>(6));
}

}  // namespace webrtc
