/*
 *  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 <memory>
#include <optional>

#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/make_ref_counted.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/test/rtc_error_matchers.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/thread.h"
#include "rtc_base/time_utils.h"
#include "rtc_base/virtual_socket_server.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/wait_until.h"

namespace webrtc {

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

// Performs an O/A exchange and waits until the signaling state is stable again.
void Negotiate(scoped_refptr<PeerConnectionTestWrapper> caller,
               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(
    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 = TimeMillis();
  scoped_refptr<FakePeriodicVideoTrackSource> periodic_track_source =
      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".
VideoSinkWants TriggerOveruseAndGetSinkWants(
    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 Thread(&virtual_socket_server_)),
        worker_thread_(Thread::Create()) {
    RTC_CHECK(network_thread_->Start());
    RTC_CHECK(worker_thread_->Start());
  }

  scoped_refptr<PeerConnectionTestWrapper> CreatePcWrapper(const char* name) {
    scoped_refptr<PeerConnectionTestWrapper> pc_wrapper =
        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:
  VirtualSocketServer virtual_socket_server_;
  std::unique_ptr<Thread> network_thread_;
  std::unique_ptr<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_THAT(WaitUntil(
                  [&] {
                    return TriggerOveruseAndGetSinkWants(fake_resource, source)
                        .max_pixel_count;
                  },
                  ::testing::Lt(pixel_count_before_overuse)),
              IsRtcOk());
}

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_THAT(WaitUntil(
                  [&] {
                    return TriggerOveruseAndGetSinkWants(fake_resource, source)
                        .max_pixel_count;
                  },
                  ::testing::Lt(pixel_count_before_overuse)),
              IsRtcOk());
}

}  // namespace webrtc
