/*
 *  Copyright (c) 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/video/send_delay_stats.h"

#include "webrtc/test/gtest.h"
#include "webrtc/system_wrappers/include/metrics.h"
#include "webrtc/system_wrappers/include/metrics_default.h"

namespace webrtc {
namespace {
const uint32_t kSsrc1 = 17;
const uint32_t kSsrc2 = 42;
const uint32_t kRtxSsrc1 = 18;
const uint32_t kRtxSsrc2 = 43;
const uint16_t kPacketId = 2345;
const int64_t kMaxPacketDelayMs = 11000;
const int kMinRequiredPeriodicSamples = 5;
const int kProcessIntervalMs = 2000;
}  // namespace

class SendDelayStatsTest : public ::testing::Test {
 public:
  SendDelayStatsTest() : clock_(1234), config_(CreateConfig()) {}
  virtual ~SendDelayStatsTest() {}

 protected:
  virtual void SetUp() {
    stats_.reset(new SendDelayStats(&clock_));
    stats_->AddSsrcs(config_);
  }

  VideoSendStream::Config CreateConfig() {
    VideoSendStream::Config config(nullptr);
    config.rtp.ssrcs.push_back(kSsrc1);
    config.rtp.ssrcs.push_back(kSsrc2);
    config.rtp.rtx.ssrcs.push_back(kRtxSsrc1);
    config.rtp.rtx.ssrcs.push_back(kRtxSsrc2);
    return config;
  }

  void OnSendPacket(uint16_t id, uint32_t ssrc) {
    OnSendPacket(id, ssrc, clock_.TimeInMilliseconds());
  }

  void OnSendPacket(uint16_t id, uint32_t ssrc, int64_t capture_ms) {
    SendPacketObserver* observer = stats_.get();
    observer->OnSendPacket(id, capture_ms, ssrc);
  }

  bool OnSentPacket(uint16_t id) {
    return stats_->OnSentPacket(id, clock_.TimeInMilliseconds());
  }

  SimulatedClock clock_;
  VideoSendStream::Config config_;
  std::unique_ptr<SendDelayStats> stats_;
};

TEST_F(SendDelayStatsTest, SentPacketFound) {
  EXPECT_FALSE(OnSentPacket(kPacketId));
  OnSendPacket(kPacketId, kSsrc1);
  EXPECT_TRUE(OnSentPacket(kPacketId));   // Packet found.
  EXPECT_FALSE(OnSentPacket(kPacketId));  // Packet removed when found.
}

TEST_F(SendDelayStatsTest, SentPacketNotFoundForNonRegisteredSsrc) {
  OnSendPacket(kPacketId, kSsrc1);
  EXPECT_TRUE(OnSentPacket(kPacketId));
  OnSendPacket(kPacketId + 1, kSsrc2);
  EXPECT_TRUE(OnSentPacket(kPacketId + 1));
  OnSendPacket(kPacketId + 2, kRtxSsrc1);  // RTX SSRC not registered.
  EXPECT_FALSE(OnSentPacket(kPacketId + 2));
}

TEST_F(SendDelayStatsTest, SentPacketFoundWithMaxSendDelay) {
  OnSendPacket(kPacketId, kSsrc1);
  clock_.AdvanceTimeMilliseconds(kMaxPacketDelayMs - 1);
  OnSendPacket(kPacketId + 1, kSsrc1);       // kPacketId -> not old/removed.
  EXPECT_TRUE(OnSentPacket(kPacketId));      // Packet found.
  EXPECT_TRUE(OnSentPacket(kPacketId + 1));  // Packet found.
}

TEST_F(SendDelayStatsTest, OldPacketsRemoved) {
  const int64_t kCaptureTimeMs = clock_.TimeInMilliseconds();
  OnSendPacket(0xffffu, kSsrc1, kCaptureTimeMs);
  OnSendPacket(0u, kSsrc1, kCaptureTimeMs);
  OnSendPacket(1u, kSsrc1, kCaptureTimeMs + 1);
  clock_.AdvanceTimeMilliseconds(kMaxPacketDelayMs);  // 0xffff, 0 -> old.
  OnSendPacket(2u, kSsrc1, kCaptureTimeMs + 2);

  EXPECT_FALSE(OnSentPacket(0xffffu));  // Old removed.
  EXPECT_FALSE(OnSentPacket(0u));       // Old removed.
  EXPECT_TRUE(OnSentPacket(1u));
  EXPECT_TRUE(OnSentPacket(2u));
}

TEST_F(SendDelayStatsTest, HistogramsAreUpdated) {
  metrics::Reset();
  const int64_t kDelayMs1 = 5;
  const int64_t kDelayMs2 = 15;
  const int kNumSamples = kMinRequiredPeriodicSamples * kProcessIntervalMs /
                          (kDelayMs1 + kDelayMs2) + 1;

  uint16_t id = 0;
  for (int i = 0; i < kNumSamples; ++i) {
    OnSendPacket(++id, kSsrc1);
    clock_.AdvanceTimeMilliseconds(kDelayMs1);
    EXPECT_TRUE(OnSentPacket(id));
    OnSendPacket(++id, kSsrc2);
    clock_.AdvanceTimeMilliseconds(kDelayMs2);
    EXPECT_TRUE(OnSentPacket(id));
  }
  stats_.reset();
  EXPECT_EQ(2, metrics::NumSamples("WebRTC.Video.SendDelayInMs"));
  EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SendDelayInMs", kDelayMs1));
  EXPECT_EQ(1, metrics::NumEvents("WebRTC.Video.SendDelayInMs", kDelayMs2));
}

}  // namespace webrtc
