/*
 *  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/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;
  std::unique_ptr<RtcEventLog> null_event_log = RtcEventLog::CreateNull();
  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 = 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.get());

  // TODO(nisse): Update AudioSendStream to not require send_transport when a
  // MediaTransport is provided.
  AudioSendStream::Config send_config(&send_transport, 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.get(), 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.get(),
      /*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
