/*
 *  Copyright (c) 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 "absl/memory/memory.h"
#include "api/audio_codecs/audio_decoder_factory_template.h"
#include "api/audio_codecs/audio_encoder_factory_template.h"
#include "api/audio_codecs/opus/audio_decoder_opus.h"
#include "api/audio_codecs/opus/audio_encoder_opus.h"
#include "api/media_transport_config.h"
#include "api/task_queue/default_task_queue_factory.h"
#include "api/test/loopback_media_transport.h"
#include "api/test/mock_audio_mixer.h"
#include "audio/audio_receive_stream.h"
#include "audio/audio_send_stream.h"
#include "call/rtp_transport_controller_send.h"
#include "call/test/mock_bitrate_allocator.h"
#include "logging/rtc_event_log/rtc_event_log.h"
#include "modules/audio_device/include/test_audio_device.h"
#include "modules/audio_mixer/audio_mixer_impl.h"
#include "modules/audio_processing/include/mock_audio_processing.h"
#include "modules/utility/include/process_thread.h"
#include "rtc_base/time_utils.h"
#include "test/gtest.h"
#include "test/mock_transport.h"

namespace webrtc {
namespace test {

namespace {
using ::testing::NiceMock;

constexpr int kPayloadTypeOpus = 17;
constexpr int kSamplingFrequency = 48000;
constexpr int kNumChannels = 2;
constexpr int kWantedSamples = 3000;
constexpr int kTestTimeoutMs = 2 * rtc::kNumMillisecsPerSec;

class TestRenderer : public TestAudioDeviceModule::Renderer {
 public:
  TestRenderer(int sampling_frequency, int num_channels, size_t wanted_samples)
      : sampling_frequency_(sampling_frequency),
        num_channels_(num_channels),
        wanted_samples_(wanted_samples) {}
  ~TestRenderer() override = default;

  int SamplingFrequency() const override { return sampling_frequency_; }
  int NumChannels() const override { return num_channels_; }

  bool Render(rtc::ArrayView<const int16_t> data) override {
    if (data.size() >= wanted_samples_) {
      return false;
    }
    wanted_samples_ -= data.size();
    return true;
  }

 private:
  const int sampling_frequency_;
  const int num_channels_;
  size_t wanted_samples_;
};

}  // namespace

TEST(AudioWithMediaTransport, DeliversAudio) {
  std::unique_ptr<rtc::Thread> transport_thread = rtc::Thread::Create();
  transport_thread->Start();
  MediaTransportPair transport_pair(transport_thread.get());
  NiceMock<MockTransport> rtcp_send_transport;
  NiceMock<MockTransport> send_transport;
  RtcEventLogNull null_event_log;
  NiceMock<MockBitrateAllocator> bitrate_allocator;

  rtc::scoped_refptr<TestAudioDeviceModule> audio_device =
      TestAudioDeviceModule::CreateTestAudioDeviceModule(
          TestAudioDeviceModule::CreatePulsedNoiseCapturer(
              /* max_amplitude= */ 10000, kSamplingFrequency, kNumChannels),
          absl::make_unique<TestRenderer>(kSamplingFrequency, kNumChannels,
                                          kWantedSamples));

  AudioState::Config audio_config;
  audio_config.audio_mixer = AudioMixerImpl::Create();
  // TODO(nisse): Is a mock AudioProcessing enough?
  audio_config.audio_processing =
      new rtc::RefCountedObject<MockAudioProcessing>();
  audio_config.audio_device_module = audio_device;
  rtc::scoped_refptr<AudioState> audio_state = AudioState::Create(audio_config);

  // TODO(nisse): Use some lossless codec?
  const SdpAudioFormat audio_format("opus", kSamplingFrequency, kNumChannels);

  // Setup receive stream;
  webrtc::AudioReceiveStream::Config receive_config;
  // TODO(nisse): Update AudioReceiveStream to not require rtcp_send_transport
  // when a MediaTransport is provided.
  receive_config.rtcp_send_transport = &rtcp_send_transport;
  receive_config.media_transport_config.media_transport =
      transport_pair.first();
  receive_config.decoder_map.emplace(kPayloadTypeOpus, audio_format);
  receive_config.decoder_factory =
      CreateAudioDecoderFactory<AudioDecoderOpus>();

  std::unique_ptr<ProcessThread> receive_process_thread =
      ProcessThread::Create("audio recv thread");

  webrtc::internal::AudioReceiveStream receive_stream(
      Clock::GetRealTimeClock(),
      /*receiver_controller=*/nullptr,
      /*packet_router=*/nullptr, receive_process_thread.get(), receive_config,
      audio_state, &null_event_log);

  // TODO(nisse): Update AudioSendStream to not require send_transport when a
  // MediaTransport is provided.
  AudioSendStream::Config send_config(
      &send_transport, webrtc::MediaTransportConfig(transport_pair.second()));
  send_config.send_codec_spec =
      AudioSendStream::Config::SendCodecSpec(kPayloadTypeOpus, audio_format);
  send_config.encoder_factory = CreateAudioEncoderFactory<AudioEncoderOpus>();
  std::unique_ptr<ProcessThread> send_process_thread =
      ProcessThread::Create("audio send thread");
  std::unique_ptr<TaskQueueFactory> task_queue_factory =
      CreateDefaultTaskQueueFactory();
  RtpTransportControllerSend rtp_transport(
      Clock::GetRealTimeClock(), &null_event_log, nullptr, nullptr,
      BitrateConstraints(), ProcessThread::Create("Pacer"),
      task_queue_factory.get());
  webrtc::internal::AudioSendStream send_stream(
      Clock::GetRealTimeClock(), send_config, audio_state,
      task_queue_factory.get(), send_process_thread.get(), &rtp_transport,
      &bitrate_allocator, &null_event_log,
      /*rtcp_rtt_stats=*/nullptr, absl::optional<RtpState>());

  audio_device->Init();  // Starts thread.
  audio_device->RegisterAudioCallback(audio_state->audio_transport());

  receive_stream.Start();
  send_stream.Start();
  audio_device->StartPlayout();
  audio_device->StartRecording();

  EXPECT_TRUE(audio_device->WaitForPlayoutEnd(kTestTimeoutMs));

  audio_device->StopRecording();
  audio_device->StopPlayout();
  receive_stream.Stop();
  send_stream.Stop();
}

}  // namespace test
}  // namespace webrtc
