/*
 *  Copyright 2020 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 <stdint.h>

#include <memory>
#include <optional>
#include <string>

#include "api/adaptation/resource.h"
#include "api/audio_codecs/builtin_audio_decoder_factory.h"
#include "api/audio_codecs/builtin_audio_encoder_factory.h"
#include "api/media_stream_interface.h"
#include "api/peer_connection_interface.h"
#include "api/rtc_error.h"
#include "api/rtp_parameters.h"
#include "api/rtp_sender_interface.h"
#include "api/scoped_refptr.h"
#include "api/video/video_source_interface.h"
#include "call/adaptation/test/fake_resource.h"
#include "pc/test/fake_periodic_video_source.h"
#include "pc/test/fake_periodic_video_track_source.h"
#include "pc/test/peer_connection_test_wrapper.h"
#include "rtc_base/checks.h"
#include "rtc_base/gunit.h"
#include "rtc_base/thread.h"
#include "rtc_base/time_utils.h"
#include "rtc_base/virtual_socket_server.h"
#include "test/gtest.h"

namespace webrtc {

const int64_t kDefaultTimeoutMs = 5000;

struct TrackWithPeriodicSource {
  rtc::scoped_refptr<VideoTrackInterface> track;
  rtc::scoped_refptr<FakePeriodicVideoTrackSource> periodic_track_source;
};

// Performs an O/A exchange and waits until the signaling state is stable again.
void Negotiate(rtc::scoped_refptr<PeerConnectionTestWrapper> caller,
               rtc::scoped_refptr<PeerConnectionTestWrapper> callee) {
  // Wire up callbacks and listeners such that a full O/A is performed in
  // response to CreateOffer().
  PeerConnectionTestWrapper::Connect(caller.get(), callee.get());
  caller->CreateOffer(PeerConnectionInterface::RTCOfferAnswerOptions());
  caller->WaitForNegotiation();
}

TrackWithPeriodicSource CreateTrackWithPeriodicSource(
    rtc::scoped_refptr<PeerConnectionFactoryInterface> factory) {
  FakePeriodicVideoSource::Config periodic_track_source_config;
  periodic_track_source_config.frame_interval_ms = 100;
  periodic_track_source_config.timestamp_offset_ms = rtc::TimeMillis();
  rtc::scoped_refptr<FakePeriodicVideoTrackSource> periodic_track_source =
      rtc::make_ref_counted<FakePeriodicVideoTrackSource>(
          periodic_track_source_config, /* remote */ false);
  TrackWithPeriodicSource track_with_source;
  track_with_source.track =
      factory->CreateVideoTrack(periodic_track_source, "PeriodicTrack");
  track_with_source.periodic_track_source = periodic_track_source;
  return track_with_source;
}

// Triggers overuse and obtains VideoSinkWants. Adaptation processing happens in
// parallel and this function makes no guarantee that the returnd VideoSinkWants
// have yet to reflect the overuse signal. Used together with EXPECT_TRUE_WAIT
// to "spam overuse until a change is observed".
rtc::VideoSinkWants TriggerOveruseAndGetSinkWants(
    rtc::scoped_refptr<FakeResource> fake_resource,
    const FakePeriodicVideoSource& source) {
  fake_resource->SetUsageState(ResourceUsageState::kOveruse);
  return source.wants();
}

class PeerConnectionAdaptationIntegrationTest : public ::testing::Test {
 public:
  PeerConnectionAdaptationIntegrationTest()
      : virtual_socket_server_(),
        network_thread_(new rtc::Thread(&virtual_socket_server_)),
        worker_thread_(rtc::Thread::Create()) {
    RTC_CHECK(network_thread_->Start());
    RTC_CHECK(worker_thread_->Start());
  }

  rtc::scoped_refptr<PeerConnectionTestWrapper> CreatePcWrapper(
      const char* name) {
    rtc::scoped_refptr<PeerConnectionTestWrapper> pc_wrapper =
        rtc::make_ref_counted<PeerConnectionTestWrapper>(
            name, &virtual_socket_server_, network_thread_.get(),
            worker_thread_.get());
    PeerConnectionInterface::RTCConfiguration config;
    config.sdp_semantics = SdpSemantics::kUnifiedPlan;
    EXPECT_TRUE(pc_wrapper->CreatePc(config, CreateBuiltinAudioEncoderFactory(),
                                     CreateBuiltinAudioDecoderFactory()));
    return pc_wrapper;
  }

 protected:
  rtc::VirtualSocketServer virtual_socket_server_;
  std::unique_ptr<rtc::Thread> network_thread_;
  std::unique_ptr<rtc::Thread> worker_thread_;
};

TEST_F(PeerConnectionAdaptationIntegrationTest,
       ResouceInjectedAfterNegotiationCausesReductionInResolution) {
  auto caller_wrapper = CreatePcWrapper("caller");
  auto caller = caller_wrapper->pc();
  auto callee_wrapper = CreatePcWrapper("callee");

  // Adding a track and negotiating ensures that a VideoSendStream exists.
  TrackWithPeriodicSource track_with_source =
      CreateTrackWithPeriodicSource(caller_wrapper->pc_factory());
  auto sender = caller->AddTrack(track_with_source.track, {}).value();
  Negotiate(caller_wrapper, callee_wrapper);
  // Prefer degrading resolution.
  auto parameters = sender->GetParameters();
  parameters.degradation_preference = DegradationPreference::MAINTAIN_FRAMERATE;
  sender->SetParameters(parameters);

  const auto& source =
      track_with_source.periodic_track_source->fake_periodic_source();
  int pixel_count_before_overuse = source.wants().max_pixel_count;

  // Inject a fake resource and spam kOveruse until resolution becomes limited.
  auto fake_resource = FakeResource::Create("FakeResource");
  caller->AddAdaptationResource(fake_resource);
  EXPECT_TRUE_WAIT(
      TriggerOveruseAndGetSinkWants(fake_resource, source).max_pixel_count <
          pixel_count_before_overuse,
      kDefaultTimeoutMs);
}

TEST_F(PeerConnectionAdaptationIntegrationTest,
       ResouceInjectedBeforeNegotiationCausesReductionInResolution) {
  auto caller_wrapper = CreatePcWrapper("caller");
  auto caller = caller_wrapper->pc();
  auto callee_wrapper = CreatePcWrapper("callee");

  // Inject a fake resource before adding any tracks or negotiating.
  auto fake_resource = FakeResource::Create("FakeResource");
  caller->AddAdaptationResource(fake_resource);

  // Adding a track and negotiating ensures that a VideoSendStream exists.
  TrackWithPeriodicSource track_with_source =
      CreateTrackWithPeriodicSource(caller_wrapper->pc_factory());
  auto sender = caller->AddTrack(track_with_source.track, {}).value();
  Negotiate(caller_wrapper, callee_wrapper);
  // Prefer degrading resolution.
  auto parameters = sender->GetParameters();
  parameters.degradation_preference = DegradationPreference::MAINTAIN_FRAMERATE;
  sender->SetParameters(parameters);

  const auto& source =
      track_with_source.periodic_track_source->fake_periodic_source();
  int pixel_count_before_overuse = source.wants().max_pixel_count;

  // Spam kOveruse until resolution becomes limited.
  EXPECT_TRUE_WAIT(
      TriggerOveruseAndGetSinkWants(fake_resource, source).max_pixel_count <
          pixel_count_before_overuse,
      kDefaultTimeoutMs);
}

}  // namespace webrtc
