/*
 *  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/environment/environment.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/units/time_delta.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/virtual_socket_server.h"
#include "system_wrappers/include/clock.h"
#include "test/create_test_environment.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(
    Clock& clock,
    scoped_refptr<PeerConnectionFactoryInterface> factory) {
  FakePeriodicVideoSource::Config periodic_track_source_config;
  periodic_track_source_config.frame_interval = TimeDelta::Millis(100);
  periodic_track_source_config.timestamp_offset = clock.CurrentTime();
  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 returned
// 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()
      : env_(CreateTestEnvironment()),
        virtual_socket_server_(),
        network_thread_(new Thread(&virtual_socket_server_)) {
    RTC_CHECK(network_thread_->Start());
  }

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

 protected:
  const Environment env_;
  VirtualSocketServer virtual_socket_server_;
  std::unique_ptr<Thread> network_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(env_.clock(), 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(env_.clock(), 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
