/*
 *  Copyright 2019 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 <atomic>

#include "api/test/network_emulation/create_cross_traffic.h"
#include "api/test/network_emulation/cross_traffic.h"
#include "test/field_trial.h"
#include "test/gtest.h"
#include "test/scenario/scenario.h"

namespace webrtc {
namespace test {
namespace {
using Capture = VideoStreamConfig::Source::Capture;
using ContentType = VideoStreamConfig::Encoder::ContentType;
using Codec = VideoStreamConfig::Encoder::Codec;
using CodecImpl = VideoStreamConfig::Encoder::Implementation;
}  // namespace

TEST(VideoStreamTest, ReceivesFramesFromFileBasedStreams) {
  TimeDelta kRunTime = TimeDelta::Millis(500);
  std::vector<int> kFrameRates = {15, 30};
  std::deque<std::atomic<int>> frame_counts(2);
  frame_counts[0] = 0;
  frame_counts[1] = 0;
  {
    Scenario s;
    auto route =
        s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
                       {s.CreateSimulationNode(NetworkSimulationConfig())},
                       s.CreateClient("callee", CallClientConfig()),
                       {s.CreateSimulationNode(NetworkSimulationConfig())});

    s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
      c->hooks.frame_pair_handlers = {
          [&](const VideoFramePair&) { frame_counts[0]++; }};
      c->source.capture = Capture::kVideoFile;
      c->source.video_file.name = "foreman_cif";
      c->source.video_file.width = 352;
      c->source.video_file.height = 288;
      c->source.framerate = kFrameRates[0];
      c->encoder.implementation = CodecImpl::kSoftware;
      c->encoder.codec = Codec::kVideoCodecVP8;
    });
    s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
      c->hooks.frame_pair_handlers = {
          [&](const VideoFramePair&) { frame_counts[1]++; }};
      c->source.capture = Capture::kImageSlides;
      c->source.slides.images.crop.width = 320;
      c->source.slides.images.crop.height = 240;
      c->source.framerate = kFrameRates[1];
      c->encoder.implementation = CodecImpl::kSoftware;
      c->encoder.codec = Codec::kVideoCodecVP9;
    });
    s.RunFor(kRunTime);
  }
  std::vector<int> expected_counts;
  for (int fps : kFrameRates)
    expected_counts.push_back(
        static_cast<int>(kRunTime.seconds<double>() * fps * 0.8));

  EXPECT_GE(frame_counts[0], expected_counts[0]);
  EXPECT_GE(frame_counts[1], expected_counts[1]);
}

TEST(VideoStreamTest, RecievesVp8SimulcastFrames) {
  TimeDelta kRunTime = TimeDelta::Millis(500);
  int kFrameRate = 30;

  std::deque<std::atomic<int>> frame_counts(3);
  frame_counts[0] = 0;
  frame_counts[1] = 0;
  frame_counts[2] = 0;
  {
    Scenario s;
    auto route =
        s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
                       {s.CreateSimulationNode(NetworkSimulationConfig())},
                       s.CreateClient("callee", CallClientConfig()),
                       {s.CreateSimulationNode(NetworkSimulationConfig())});
    s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
      // TODO(srte): Replace with code checking for all simulcast streams when
      // there's a hook available for that.
      c->hooks.frame_pair_handlers = {[&](const VideoFramePair& info) {
        frame_counts[info.layer_id]++;
        RTC_DCHECK(info.decoded);
        printf("%i: [%3i->%3i, %i], %i->%i, \n", info.layer_id, info.capture_id,
               info.decode_id, info.repeated, info.captured->width(),
               info.decoded->width());
      }};
      c->source.framerate = kFrameRate;
      // The resolution must be high enough to allow smaller layers to be
      // created.
      c->source.generator.width = 1024;
      c->source.generator.height = 768;
      c->encoder.implementation = CodecImpl::kSoftware;
      c->encoder.codec = Codec::kVideoCodecVP8;
      // By enabling multiple spatial layers, simulcast will be enabled for VP8.
      c->encoder.layers.spatial = 3;
    });
    s.RunFor(kRunTime);
  }

  // Using high error margin to avoid flakyness.
  const int kExpectedCount =
      static_cast<int>(kRunTime.seconds<double>() * kFrameRate * 0.5);

  EXPECT_GE(frame_counts[0], kExpectedCount);
  EXPECT_GE(frame_counts[1], kExpectedCount);
  EXPECT_GE(frame_counts[2], kExpectedCount);
}

TEST(VideoStreamTest, SendsNacksOnLoss) {
  Scenario s;
  auto route =
      s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
                     {s.CreateSimulationNode([](NetworkSimulationConfig* c) {
                       c->loss_rate = 0.2;
                     })},
                     s.CreateClient("callee", CallClientConfig()),
                     {s.CreateSimulationNode(NetworkSimulationConfig())});
  // NACK retransmissions are enabled by default.
  auto video = s.CreateVideoStream(route->forward(), VideoStreamConfig());
  s.RunFor(TimeDelta::Seconds(1));
  int retransmit_packets = 0;
  for (const auto& substream : video->send()->GetStats().substreams) {
    retransmit_packets += substream.second.rtp_stats.retransmitted.packets;
  }
  EXPECT_GT(retransmit_packets, 0);
}

TEST(VideoStreamTest, SendsFecWithUlpFec) {
  Scenario s;
  auto route =
      s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
                     {s.CreateSimulationNode([](NetworkSimulationConfig* c) {
                       c->loss_rate = 0.1;
                       c->delay = TimeDelta::Millis(100);
                     })},
                     s.CreateClient("callee", CallClientConfig()),
                     {s.CreateSimulationNode(NetworkSimulationConfig())});
  auto video = s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
    // We do not allow NACK+ULPFEC for generic codec, using VP8.
    c->encoder.codec = VideoStreamConfig::Encoder::Codec::kVideoCodecVP8;
    c->stream.use_ulpfec = true;
  });
  s.RunFor(TimeDelta::Seconds(5));
  VideoSendStream::Stats video_stats = video->send()->GetStats();
  EXPECT_GT(video_stats.substreams.begin()->second.rtp_stats.fec.packets, 0u);
}
TEST(VideoStreamTest, SendsFecWithFlexFec) {
  Scenario s;
  auto route =
      s.CreateRoutes(s.CreateClient("caller", CallClientConfig()),
                     {s.CreateSimulationNode([](NetworkSimulationConfig* c) {
                       c->loss_rate = 0.1;
                       c->delay = TimeDelta::Millis(100);
                     })},
                     s.CreateClient("callee", CallClientConfig()),
                     {s.CreateSimulationNode(NetworkSimulationConfig())});
  auto video = s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
    c->stream.use_flexfec = true;
  });
  s.RunFor(TimeDelta::Seconds(5));
  VideoSendStream::Stats video_stats = video->send()->GetStats();
  EXPECT_GT(video_stats.substreams.begin()->second.rtp_stats.fec.packets, 0u);
}

TEST(VideoStreamTest, ResolutionAdaptsToAvailableBandwidth) {
  // Declared before scenario to avoid use after free.
  std::atomic<size_t> num_qvga_frames_(0);
  std::atomic<size_t> num_vga_frames_(0);

  Scenario s;
  // Link has enough capacity for VGA.
  NetworkSimulationConfig net_conf;
  net_conf.bandwidth = DataRate::KilobitsPerSec(800);
  net_conf.delay = TimeDelta::Millis(50);
  auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
    c->transport.rates.start_rate = DataRate::KilobitsPerSec(800);
  });
  auto send_net = {s.CreateSimulationNode(net_conf)};
  auto ret_net = {s.CreateSimulationNode(net_conf)};
  auto* route = s.CreateRoutes(
      client, send_net, s.CreateClient("return", CallClientConfig()), ret_net);

  s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
    c->hooks.frame_pair_handlers = {[&](const VideoFramePair& info) {
      if (info.decoded->width() == 640) {
        ++num_vga_frames_;
      } else if (info.decoded->width() == 320) {
        ++num_qvga_frames_;
      } else {
        ADD_FAILURE() << "Unexpected resolution: " << info.decoded->width();
      }
    }};
    c->source.framerate = 30;
    // The resolution must be high enough to allow smaller layers to be
    // created.
    c->source.generator.width = 640;
    c->source.generator.height = 480;
    c->encoder.implementation = CodecImpl::kSoftware;
    c->encoder.codec = Codec::kVideoCodecVP9;
    // Enable SVC.
    c->encoder.layers.spatial = 2;
  });

  // Run for a few seconds, until streams have stabilized,
  // check that we are sending VGA.
  s.RunFor(TimeDelta::Seconds(5));
  EXPECT_GT(num_vga_frames_, 0u);

  // Trigger cross traffic, run until we have seen 3 consecutive
  // seconds with no VGA frames due to reduced available bandwidth.
  auto cross_traffic = s.net()->StartCrossTraffic(CreateFakeTcpCrossTraffic(
      s.net()->CreateRoute(send_net), s.net()->CreateRoute(ret_net),
      FakeTcpConfig()));

  int num_seconds_without_vga = 0;
  int num_iterations = 0;
  do {
    ASSERT_LE(++num_iterations, 100);
    num_qvga_frames_ = 0;
    num_vga_frames_ = 0;
    s.RunFor(TimeDelta::Seconds(1));
    if (num_qvga_frames_ > 0 && num_vga_frames_ == 0) {
      ++num_seconds_without_vga;
    } else {
      num_seconds_without_vga = 0;
    }
  } while (num_seconds_without_vga < 3);

  // Stop cross traffic, make sure we recover and get VGA frames agian.
  s.net()->StopCrossTraffic(cross_traffic);
  num_qvga_frames_ = 0;
  num_vga_frames_ = 0;

  s.RunFor(TimeDelta::Seconds(40));
  EXPECT_GT(num_qvga_frames_, 0u);
  EXPECT_GT(num_vga_frames_, 0u);
}

TEST(VideoStreamTest, SuspendsBelowMinBitrate) {
  const DataRate kMinVideoBitrate = DataRate::KilobitsPerSec(30);

  // Declared before scenario to avoid use after free.
  std::atomic<Timestamp> last_frame_timestamp(Timestamp::MinusInfinity());

  Scenario s;
  NetworkSimulationConfig net_config;
  net_config.bandwidth = kMinVideoBitrate * 4;
  net_config.delay = TimeDelta::Millis(10);
  auto* client = s.CreateClient("send", [&](CallClientConfig* c) {
    // Min transmit rate needs to be lower than kMinVideoBitrate for this test
    // to make sense.
    c->transport.rates.min_rate = kMinVideoBitrate / 2;
    c->transport.rates.start_rate = kMinVideoBitrate;
    c->transport.rates.max_rate = kMinVideoBitrate * 2;
  });
  auto send_net = s.CreateMutableSimulationNode(
      [&](NetworkSimulationConfig* c) { *c = net_config; });
  auto ret_net = {s.CreateSimulationNode(net_config)};
  auto* route =
      s.CreateRoutes(client, {send_net->node()},
                     s.CreateClient("return", CallClientConfig()), ret_net);

  s.CreateVideoStream(route->forward(), [&](VideoStreamConfig* c) {
    c->hooks.frame_pair_handlers = {[&](const VideoFramePair& pair) {
      if (pair.repeated == 0) {
        last_frame_timestamp = pair.capture_time;
      }
    }};
    c->source.framerate = 30;
    c->source.generator.width = 320;
    c->source.generator.height = 180;
    c->encoder.implementation = CodecImpl::kFake;
    c->encoder.codec = Codec::kVideoCodecVP8;
    c->encoder.min_data_rate = kMinVideoBitrate;
    c->encoder.suspend_below_min_bitrate = true;
    c->stream.pad_to_rate = kMinVideoBitrate;
  });

  // Run for a few seconds, check we have received at least one frame.
  s.RunFor(TimeDelta::Seconds(2));
  EXPECT_TRUE(last_frame_timestamp.load().IsFinite());

  // Degrade network to below min bitrate.
  send_net->UpdateConfig([&](NetworkSimulationConfig* c) {
    c->bandwidth = kMinVideoBitrate * 0.9;
  });

  // Run for 20s, verify that no frames arrive that were captured after the
  // first five seconds, allowing some margin for BWE backoff to trigger and
  // packets already in the pipeline to potentially arrive.
  s.RunFor(TimeDelta::Seconds(20));
  EXPECT_GT(s.Now() - last_frame_timestamp, TimeDelta::Seconds(15));

  // Relax the network constraints and run for a while more, verify that we
  // start receiving frames again.
  send_net->UpdateConfig(
      [&](NetworkSimulationConfig* c) { c->bandwidth = kMinVideoBitrate * 4; });
  last_frame_timestamp = Timestamp::MinusInfinity();
  s.RunFor(TimeDelta::Seconds(15));
  EXPECT_TRUE(last_frame_timestamp.load().IsFinite());
}

}  // namespace test
}  // namespace webrtc
