/*
 *  Copyright (c) 2023 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 "modules/audio_device/test_audio_device_impl.h"

#include <memory>
#include <optional>
#include <utility>

#include "api/audio/audio_device.h"
#include "api/audio/audio_device_defines.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "modules/audio_device/audio_device_buffer.h"
#include "modules/audio_device/audio_device_generic.h"
#include "modules/audio_device/include/test_audio_device.h"
#include "rtc_base/checks.h"
#include "rtc_base/synchronization/mutex.h"
#include "test/gmock.h"
#include "test/gtest.h"
#include "test/time_controller/simulated_time_controller.h"

namespace webrtc {
namespace {

using ::testing::ElementsAre;

constexpr Timestamp kStartTime = Timestamp::Millis(10000);

class TestAudioTransport : public AudioTransport {
 public:
  enum class Mode { kPlaying, kRecording };

  explicit TestAudioTransport(Mode mode) : mode_(mode) {}
  ~TestAudioTransport() override = default;

  int32_t RecordedDataIsAvailable(
      const void* audioSamples,
      size_t samples_per_channel,
      size_t bytes_per_sample,
      size_t number_of_channels,
      uint32_t samples_per_second,
      uint32_t total_delay_ms,
      int32_t clock_drift,
      uint32_t current_mic_level,
      bool key_pressed,
      uint32_t& new_mic_level,
      std::optional<int64_t> estimated_capture_time_ns) override {
    new_mic_level = 1;

    if (mode_ != Mode::kRecording) {
      EXPECT_TRUE(false) << "RecordedDataIsAvailable mustn't be called when "
                            "mode isn't kRecording";
      return -1;
    }

    MutexLock lock(&mutex_);
    samples_per_channel_.push_back(samples_per_channel);
    number_of_channels_.push_back(number_of_channels);
    bytes_per_sample_.push_back(bytes_per_sample);
    samples_per_second_.push_back(samples_per_second);
    return 0;
  }

  int32_t NeedMorePlayData(size_t samples_per_channel,
                           size_t bytes_per_sample,
                           size_t number_of_channels,
                           uint32_t samples_per_second,
                           void* audio_samples,
                           size_t& samples_out,
                           int64_t* elapsed_time_ms,
                           int64_t* ntp_time_ms) override {
    const size_t num_bytes = samples_per_channel * number_of_channels;
    std::memset(audio_samples, 1, num_bytes);
    samples_out = samples_per_channel * number_of_channels;
    *elapsed_time_ms = 0;
    *ntp_time_ms = 0;

    if (mode_ != Mode::kPlaying) {
      EXPECT_TRUE(false)
          << "NeedMorePlayData mustn't be called when mode isn't kPlaying";
      return -1;
    }

    MutexLock lock(&mutex_);
    samples_per_channel_.push_back(samples_per_channel);
    number_of_channels_.push_back(number_of_channels);
    bytes_per_sample_.push_back(bytes_per_sample);
    samples_per_second_.push_back(samples_per_second);
    return 0;
  }

  int32_t RecordedDataIsAvailable(const void* audio_samples,
                                  size_t samples_per_channel,
                                  size_t bytes_per_sample,
                                  size_t number_of_channels,
                                  uint32_t samples_per_second,
                                  uint32_t total_delay_ms,
                                  int32_t clockDrift,
                                  uint32_t current_mic_level,
                                  bool key_pressed,
                                  uint32_t& new_mic_level) override {
    RTC_CHECK(false) << "This methods should be never executed";
  }

  void PullRenderData(int bits_per_sample,
                      int sample_rate,
                      size_t number_of_channels,
                      size_t number_of_frames,
                      void* audio_data,
                      int64_t* elapsed_time_ms,
                      int64_t* ntp_time_ms) override {
    RTC_CHECK(false) << "This methods should be never executed";
  }

  std::vector<size_t> samples_per_channel() const {
    MutexLock lock(&mutex_);
    return samples_per_channel_;
  }
  std::vector<size_t> number_of_channels() const {
    MutexLock lock(&mutex_);
    return number_of_channels_;
  }
  std::vector<size_t> bytes_per_sample() const {
    MutexLock lock(&mutex_);
    return bytes_per_sample_;
  }
  std::vector<size_t> samples_per_second() const {
    MutexLock lock(&mutex_);
    return samples_per_second_;
  }

 private:
  const Mode mode_;

  mutable Mutex mutex_;
  std::vector<size_t> samples_per_channel_ RTC_GUARDED_BY(mutex_);
  std::vector<size_t> number_of_channels_ RTC_GUARDED_BY(mutex_);
  std::vector<size_t> bytes_per_sample_ RTC_GUARDED_BY(mutex_);
  std::vector<size_t> samples_per_second_ RTC_GUARDED_BY(mutex_);
};

TEST(TestAudioDeviceTest, EnablingRecordingProducesAudio) {
  GlobalSimulatedTimeController time_controller(kStartTime);
  TestAudioTransport audio_transport(TestAudioTransport::Mode::kRecording);
  AudioDeviceBuffer audio_buffer(time_controller.GetTaskQueueFactory());
  ASSERT_EQ(audio_buffer.RegisterAudioCallback(&audio_transport), 0);
  std::unique_ptr<TestAudioDeviceModule::PulsedNoiseCapturer> capturer =
      TestAudioDeviceModule::CreatePulsedNoiseCapturer(
          /*max_amplitude=*/1000,
          /*sampling_frequency_in_hz=*/48000, /*num_channels=*/2);

  TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
                               std::move(capturer),
                               /*renderer=*/nullptr);
  ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);
  audio_device.AttachAudioBuffer(&audio_buffer);

  EXPECT_FALSE(audio_device.RecordingIsInitialized());
  ASSERT_EQ(audio_device.InitRecording(), 0);
  EXPECT_TRUE(audio_device.RecordingIsInitialized());
  audio_buffer.StartRecording();
  ASSERT_EQ(audio_device.StartRecording(), 0);
  time_controller.AdvanceTime(TimeDelta::Millis(10));
  ASSERT_TRUE(audio_device.Recording());
  time_controller.AdvanceTime(TimeDelta::Millis(10));
  ASSERT_EQ(audio_device.StopRecording(), 0);
  audio_buffer.StopRecording();

  EXPECT_THAT(audio_transport.samples_per_channel(),
              ElementsAre(480, 480, 480));
  EXPECT_THAT(audio_transport.number_of_channels(), ElementsAre(2, 2, 2));
  EXPECT_THAT(audio_transport.bytes_per_sample(), ElementsAre(4, 4, 4));
  EXPECT_THAT(audio_transport.samples_per_second(),
              ElementsAre(48000, 48000, 48000));
}

TEST(TestAudioDeviceTest, RecordingIsAvailableWhenCapturerIsSet) {
  GlobalSimulatedTimeController time_controller(kStartTime);
  std::unique_ptr<TestAudioDeviceModule::PulsedNoiseCapturer> capturer =
      TestAudioDeviceModule::CreatePulsedNoiseCapturer(
          /*max_amplitude=*/1000,
          /*sampling_frequency_in_hz=*/48000, /*num_channels=*/2);

  TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
                               std::move(capturer),
                               /*renderer=*/nullptr);
  ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);

  bool available;
  EXPECT_EQ(audio_device.RecordingIsAvailable(available), 0);
  EXPECT_TRUE(available);
}

TEST(TestAudioDeviceTest, RecordingIsNotAvailableWhenCapturerIsNotSet) {
  GlobalSimulatedTimeController time_controller(kStartTime);
  TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
                               /*capturer=*/nullptr,
                               /*renderer=*/nullptr);
  ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);

  bool available;
  EXPECT_EQ(audio_device.RecordingIsAvailable(available), 0);
  EXPECT_FALSE(available);
}

TEST(TestAudioDeviceTest, EnablingPlayoutProducesAudio) {
  GlobalSimulatedTimeController time_controller(kStartTime);
  TestAudioTransport audio_transport(TestAudioTransport::Mode::kPlaying);
  AudioDeviceBuffer audio_buffer(time_controller.GetTaskQueueFactory());
  ASSERT_EQ(audio_buffer.RegisterAudioCallback(&audio_transport), 0);
  std::unique_ptr<TestAudioDeviceModule::Renderer> renderer =
      TestAudioDeviceModule::CreateDiscardRenderer(
          /*sampling_frequency_in_hz=*/48000, /*num_channels=*/2);

  TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
                               /*capturer=*/nullptr, std::move(renderer));
  ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);
  audio_device.AttachAudioBuffer(&audio_buffer);

  EXPECT_FALSE(audio_device.PlayoutIsInitialized());
  ASSERT_EQ(audio_device.InitPlayout(), 0);
  EXPECT_TRUE(audio_device.PlayoutIsInitialized());
  audio_buffer.StartPlayout();
  ASSERT_EQ(audio_device.StartPlayout(), 0);
  time_controller.AdvanceTime(TimeDelta::Millis(10));
  ASSERT_TRUE(audio_device.Playing());
  time_controller.AdvanceTime(TimeDelta::Millis(10));
  ASSERT_EQ(audio_device.StopPlayout(), 0);
  audio_buffer.StopPlayout();

  EXPECT_THAT(audio_transport.samples_per_channel(),
              ElementsAre(480, 480, 480));
  EXPECT_THAT(audio_transport.number_of_channels(), ElementsAre(2, 2, 2));
  EXPECT_THAT(audio_transport.bytes_per_sample(), ElementsAre(4, 4, 4));
  EXPECT_THAT(audio_transport.samples_per_second(),
              ElementsAre(48000, 48000, 48000));
}

TEST(TestAudioDeviceTest, PlayoutIsAvailableWhenRendererIsSet) {
  GlobalSimulatedTimeController time_controller(kStartTime);
  std::unique_ptr<TestAudioDeviceModule::Renderer> renderer =
      TestAudioDeviceModule::CreateDiscardRenderer(
          /*sampling_frequency_in_hz=*/48000, /*num_channels=*/2);

  TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
                               /*capturer=*/nullptr, std::move(renderer));
  ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);

  bool available;
  EXPECT_EQ(audio_device.PlayoutIsAvailable(available), 0);
  EXPECT_TRUE(available);
}

TEST(TestAudioDeviceTest, PlayoutIsNotAvailableWhenRendererIsNotSet) {
  GlobalSimulatedTimeController time_controller(kStartTime);
  TestAudioDevice audio_device(time_controller.GetTaskQueueFactory(),
                               /*capturer=*/nullptr,
                               /*renderer=*/nullptr);
  ASSERT_EQ(audio_device.Init(), AudioDeviceGeneric::InitStatus::OK);

  bool available;
  EXPECT_EQ(audio_device.PlayoutIsAvailable(available), 0);
  EXPECT_FALSE(available);
}

}  // namespace
}  // namespace webrtc
