/*
 *  Copyright 2018 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 <optional>

#include "api/test/video/function_video_encoder_factory.h"
#include "modules/video_coding/codecs/vp8/include/vp8.h"
#include "rtc_base/synchronization/mutex.h"
#include "system_wrappers/include/metrics.h"
#include "test/call_test.h"
#include "test/gtest.h"
#include "test/video_test_constants.h"

namespace webrtc {
namespace {
enum : int {  // The first valid value is 1.
  kTransportSequenceNumberExtensionId = 1,
  kVideoContentTypeExtensionId,
};
}  // namespace

class HistogramTest : public test::CallTest {
 public:
  HistogramTest() {
    RegisterRtpExtension(RtpExtension(RtpExtension::kTransportSequenceNumberUri,
                                      kTransportSequenceNumberExtensionId));
    RegisterRtpExtension(RtpExtension(RtpExtension::kVideoContentTypeUri,
                                      kVideoContentTypeExtensionId));
  }

 protected:
  void VerifyHistogramStats(bool use_rtx, bool use_fec, bool screenshare);
};

void HistogramTest::VerifyHistogramStats(bool use_rtx,
                                         bool use_fec,
                                         bool screenshare) {
  class FrameObserver : public test::EndToEndTest,
                        public rtc::VideoSinkInterface<VideoFrame> {
   public:
    FrameObserver(bool use_rtx, bool use_fec, bool screenshare)
        : EndToEndTest(test::VideoTestConstants::kLongTimeout),
          use_rtx_(use_rtx),
          use_fec_(use_fec),
          screenshare_(screenshare),
          // This test uses NACK, so to send FEC we can't use a fake encoder.
          encoder_factory_(
              [](const Environment& env, const SdpVideoFormat& format) {
                return CreateVp8Encoder(env);
              }),
          num_frames_received_(0) {}

   private:
    void OnFrame(const VideoFrame& video_frame) override {
      // The RTT is needed to estimate `ntp_time_ms` which is used by
      // end-to-end delay stats. Therefore, start counting received frames once
      // `ntp_time_ms` is valid.
      if (video_frame.ntp_time_ms() > 0 &&
          Clock::GetRealTimeClock()->CurrentNtpInMilliseconds() >=
              video_frame.ntp_time_ms()) {
        MutexLock lock(&mutex_);
        ++num_frames_received_;
      }
    }

    Action OnSendRtp(rtc::ArrayView<const uint8_t> packet) override {
      if (MinMetricRunTimePassed() && MinNumberOfFramesReceived())
        observation_complete_.Set();

      return SEND_PACKET;
    }

    bool MinMetricRunTimePassed() {
      int64_t now_ms = Clock::GetRealTimeClock()->TimeInMilliseconds();
      if (!start_runtime_ms_)
        start_runtime_ms_ = now_ms;

      int64_t elapsed_sec = (now_ms - *start_runtime_ms_) / 1000;
      return elapsed_sec > metrics::kMinRunTimeInSeconds * 2;
    }

    bool MinNumberOfFramesReceived() const {
      const int kMinRequiredHistogramSamples = 200;
      MutexLock lock(&mutex_);
      return num_frames_received_ > kMinRequiredHistogramSamples;
    }

    void ModifyVideoConfigs(
        VideoSendStream::Config* send_config,
        std::vector<VideoReceiveStreamInterface::Config>* receive_configs,
        VideoEncoderConfig* encoder_config) override {
      // NACK
      send_config->rtp.nack.rtp_history_ms =
          test::VideoTestConstants::kNackRtpHistoryMs;
      (*receive_configs)[0].rtp.nack.rtp_history_ms =
          test::VideoTestConstants::kNackRtpHistoryMs;
      (*receive_configs)[0].renderer = this;
      // FEC
      if (use_fec_) {
        send_config->rtp.ulpfec.ulpfec_payload_type =
            test::VideoTestConstants::kUlpfecPayloadType;
        send_config->rtp.ulpfec.red_payload_type =
            test::VideoTestConstants::kRedPayloadType;
        send_config->encoder_settings.encoder_factory = &encoder_factory_;
        send_config->rtp.payload_name = "VP8";
        encoder_config->codec_type = kVideoCodecVP8;
        (*receive_configs)[0].decoders[0].video_format = SdpVideoFormat::VP8();
        (*receive_configs)[0].rtp.red_payload_type =
            test::VideoTestConstants::kRedPayloadType;
        (*receive_configs)[0].rtp.ulpfec_payload_type =
            test::VideoTestConstants::kUlpfecPayloadType;
      }
      // RTX
      if (use_rtx_) {
        send_config->rtp.rtx.ssrcs.push_back(
            test::VideoTestConstants::kSendRtxSsrcs[0]);
        send_config->rtp.rtx.payload_type =
            test::VideoTestConstants::kSendRtxPayloadType;
        (*receive_configs)[0].rtp.rtx_ssrc =
            test::VideoTestConstants::kSendRtxSsrcs[0];
        (*receive_configs)[0].rtp.rtx_associated_payload_types
            [test::VideoTestConstants::kSendRtxPayloadType] =
            test::VideoTestConstants::kFakeVideoSendPayloadType;
        if (use_fec_) {
          send_config->rtp.ulpfec.red_rtx_payload_type =
              test::VideoTestConstants::kRtxRedPayloadType;
          (*receive_configs)[0].rtp.rtx_associated_payload_types
              [test::VideoTestConstants::kRtxRedPayloadType] =
              test::VideoTestConstants::kSendRtxPayloadType;
        }
      }
      // RTT needed for RemoteNtpTimeEstimator for the receive stream.
      (*receive_configs)[0].rtp.rtcp_xr.receiver_reference_time_report = true;
      encoder_config->content_type =
          screenshare_ ? VideoEncoderConfig::ContentType::kScreen
                       : VideoEncoderConfig::ContentType::kRealtimeVideo;
    }

    void PerformTest() override {
      EXPECT_TRUE(Wait()) << "Timed out waiting for min frames to be received.";
    }

    mutable Mutex mutex_;
    const bool use_rtx_;
    const bool use_fec_;
    const bool screenshare_;
    test::FunctionVideoEncoderFactory encoder_factory_;
    std::optional<int64_t> start_runtime_ms_;
    int num_frames_received_ RTC_GUARDED_BY(&mutex_);
  } test(use_rtx, use_fec, screenshare);

  metrics::Reset();
  RunBaseTest(&test);

  const std::string video_prefix =
      screenshare ? "WebRTC.Video.Screenshare." : "WebRTC.Video.";

  // Verify that stats have been updated once.
  EXPECT_METRIC_EQ(2, metrics::NumSamples("WebRTC.Call.LifetimeInSeconds"));
  EXPECT_METRIC_EQ(1, metrics::NumSamples(
                          "WebRTC.Call.TimeReceivingVideoRtpPacketsInSeconds"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples("WebRTC.Call.VideoBitrateReceivedInKbps"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples("WebRTC.Call.RtcpBitrateReceivedInBps"));
  EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Call.BitrateReceivedInKbps"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples("WebRTC.Call.EstimatedSendBitrateInKbps"));
  EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Call.PacerBitrateInKbps"));

  EXPECT_METRIC_EQ(
      1, metrics::NumSamples("WebRTC.Video.SendStreamLifetimeInSeconds"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples("WebRTC.Video.ReceiveStreamLifetimeInSeconds"));

  EXPECT_METRIC_EQ(
      1, metrics::NumSamples("WebRTC.Video.NackPacketsSentPerMinute"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples(video_prefix + "NackPacketsReceivedPerMinute"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples("WebRTC.Video.FirPacketsSentPerMinute"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples(video_prefix + "FirPacketsReceivedPerMinute"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples("WebRTC.Video.PliPacketsSentPerMinute"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples(video_prefix + "PliPacketsReceivedPerMinute"));

  EXPECT_METRIC_EQ(
      1, metrics::NumSamples(video_prefix + "KeyFramesSentInPermille"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples("WebRTC.Video.KeyFramesReceivedInPermille"));

  EXPECT_METRIC_EQ(
      1, metrics::NumSamples(video_prefix + "SentPacketsLostInPercent"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples("WebRTC.Video.ReceivedPacketsLostInPercent"));

  EXPECT_METRIC_EQ(1, metrics::NumSamples(video_prefix + "InputWidthInPixels"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples(video_prefix + "InputHeightInPixels"));
  EXPECT_METRIC_EQ(1, metrics::NumSamples(video_prefix + "SentWidthInPixels"));
  EXPECT_METRIC_EQ(1, metrics::NumSamples(video_prefix + "SentHeightInPixels"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples(video_prefix + "ReceivedWidthInPixels"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples(video_prefix + "ReceivedHeightInPixels"));

  EXPECT_METRIC_EQ(1,
                   metrics::NumEvents(video_prefix + "InputWidthInPixels",
                                      test::VideoTestConstants::kDefaultWidth));
  EXPECT_METRIC_EQ(
      1, metrics::NumEvents(video_prefix + "InputHeightInPixels",
                            test::VideoTestConstants::kDefaultHeight));
  EXPECT_METRIC_EQ(1,
                   metrics::NumEvents(video_prefix + "SentWidthInPixels",
                                      test::VideoTestConstants::kDefaultWidth));
  EXPECT_METRIC_EQ(
      1, metrics::NumEvents(video_prefix + "SentHeightInPixels",
                            test::VideoTestConstants::kDefaultHeight));
  EXPECT_METRIC_EQ(1,
                   metrics::NumEvents(video_prefix + "ReceivedWidthInPixels",
                                      test::VideoTestConstants::kDefaultWidth));
  EXPECT_METRIC_EQ(
      1, metrics::NumEvents(video_prefix + "ReceivedHeightInPixels",
                            test::VideoTestConstants::kDefaultHeight));

  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples(video_prefix + "InputFramesPerSecond"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples(video_prefix + "SentFramesPerSecond"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples("WebRTC.Video.DecodedFramesPerSecond"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples("WebRTC.Video.RenderFramesPerSecond"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples("WebRTC.Video.DelayedFramesToRenderer"));

  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples("WebRTC.Video.JitterBufferDelayInMs"));
  EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.TargetDelayInMs"));
  EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.CurrentDelayInMs"));
  EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.OnewayDelayInMs"));

  EXPECT_METRIC_EQ(1, metrics::NumSamples(video_prefix + "EndToEndDelayInMs"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples(video_prefix + "EndToEndDelayMaxInMs"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples(video_prefix + "InterframeDelayInMs"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples(video_prefix + "InterframeDelayMaxInMs"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples("WebRTC.Video.RenderSqrtPixelsPerSecond"));

  EXPECT_METRIC_EQ(1, metrics::NumSamples(video_prefix + "EncodeTimeInMs"));
  EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.DecodeTimeInMs"));

  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples(video_prefix + "NumberOfPauseEvents"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples(video_prefix + "PausedTimeInPercent"));

  EXPECT_METRIC_EQ(1, metrics::NumSamples(video_prefix + "BitrateSentInKbps"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples("WebRTC.Video.BitrateReceivedInKbps"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples(video_prefix + "MediaBitrateSentInKbps"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples("WebRTC.Video.MediaBitrateReceivedInKbps"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples(video_prefix + "PaddingBitrateSentInKbps"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples("WebRTC.Video.PaddingBitrateReceivedInKbps"));
  EXPECT_METRIC_EQ(
      1, metrics::NumSamples(video_prefix + "RetransmittedBitrateSentInKbps"));
  EXPECT_METRIC_EQ(1, metrics::NumSamples(
                          "WebRTC.Video.RetransmittedBitrateReceivedInKbps"));

  EXPECT_METRIC_EQ(1, metrics::NumSamples("WebRTC.Video.SendDelayInMs"));
  EXPECT_METRIC_EQ(1, metrics::NumSamples(video_prefix + "SendSideDelayInMs"));
  EXPECT_METRIC_EQ(1,
                   metrics::NumSamples(video_prefix + "SendSideDelayMaxInMs"));

  int num_rtx_samples = use_rtx ? 1 : 0;
  EXPECT_METRIC_EQ(num_rtx_samples,
                   metrics::NumSamples("WebRTC.Video.RtxBitrateSentInKbps"));
  EXPECT_METRIC_EQ(
      num_rtx_samples,
      metrics::NumSamples("WebRTC.Video.RtxBitrateReceivedInKbps"));

  int num_red_samples = use_fec ? 1 : 0;
  EXPECT_METRIC_EQ(num_red_samples,
                   metrics::NumSamples("WebRTC.Video.FecBitrateSentInKbps"));
  EXPECT_METRIC_EQ(
      num_red_samples,
      metrics::NumSamples("WebRTC.Video.FecBitrateReceivedInKbps"));
  EXPECT_METRIC_EQ(
      num_red_samples,
      metrics::NumSamples("WebRTC.Video.ReceivedFecPacketsInPercent"));
}

TEST_F(HistogramTest, VerifyStatsWithRtx) {
  const bool kEnabledRtx = true;
  const bool kEnabledRed = false;
  const bool kScreenshare = false;
  VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare);
}

TEST_F(HistogramTest, VerifyStatsWithRed) {
  const bool kEnabledRtx = false;
  const bool kEnabledRed = true;
  const bool kScreenshare = false;
  VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare);
}

TEST_F(HistogramTest, VerifyStatsWithScreenshare) {
  const bool kEnabledRtx = false;
  const bool kEnabledRed = false;
  const bool kScreenshare = true;
  VerifyHistogramStats(kEnabledRtx, kEnabledRed, kScreenshare);
}

}  // namespace webrtc
