/*
 *  Copyright (c) 2015 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 "audio/audio_state.h"

#include <cmath>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
#include <memory>
#include <numbers>
#include <utility>
#include <vector>

#include "absl/functional/any_invocable.h"
#include "absl/strings/string_view.h"
#include "api/audio/audio_frame.h"
#include "api/audio/audio_frame_processor.h"
#include "api/audio/audio_mixer.h"
#include "api/location.h"
#include "api/make_ref_counted.h"
#include "api/scoped_refptr.h"
#include "api/task_queue/task_queue_base.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/task_queue/test/mock_task_queue_base.h"
#include "call/audio_state.h"
#include "call/test/mock_audio_receive_stream.h"
#include "call/test/mock_audio_send_stream.h"
#include "modules/async_audio_processing/async_audio_processing.h"
#include "modules/audio_device/include/mock_audio_device.h"
#include "modules/audio_mixer/audio_mixer_impl.h"
#include "modules/audio_processing/include/mock_audio_processing.h"
#include "rtc_base/thread.h"
#include "test/gmock.h"
#include "test/gtest.h"

namespace webrtc {
namespace test {
namespace {

using ::testing::_;
using ::testing::InSequence;
using ::testing::Matcher;
using ::testing::NiceMock;
using ::testing::StrictMock;
using ::testing::Values;

constexpr int kSampleRate = 16000;
constexpr int kNumberOfChannels = 1;

struct FakeAsyncAudioProcessingHelper {
  class FakeTaskQueue : public StrictMock<MockTaskQueueBase> {
   public:
    FakeTaskQueue() = default;

    void Delete() override { delete this; }
    void PostTaskImpl(absl::AnyInvocable<void() &&> task,
                      const PostTaskTraits& /*traits*/,
                      const Location& /*location*/) override {
      std::move(task)();
    }
  };

  class FakeTaskQueueFactory : public TaskQueueFactory {
   public:
    FakeTaskQueueFactory() = default;
    ~FakeTaskQueueFactory() override = default;
    std::unique_ptr<TaskQueueBase, TaskQueueDeleter> CreateTaskQueue(
        absl::string_view /* name */,
        Priority /* priority */) const override {
      return std::unique_ptr<TaskQueueBase, TaskQueueDeleter>(
          new FakeTaskQueue());
    }
  };

  class MockAudioFrameProcessor : public AudioFrameProcessor {
   public:
    ~MockAudioFrameProcessor() override = default;

    MOCK_METHOD(void, ProcessCalled, ());
    MOCK_METHOD(void, SinkSet, ());
    MOCK_METHOD(void, SinkCleared, ());

    void Process(std::unique_ptr<AudioFrame> frame) override {
      ProcessCalled();
      sink_callback_(std::move(frame));
    }

    void SetSink(OnAudioFrameCallback sink_callback) override {
      sink_callback_ = std::move(sink_callback);
      if (sink_callback_ == nullptr)
        SinkCleared();
      else
        SinkSet();
    }

   private:
    OnAudioFrameCallback sink_callback_;
  };

  NiceMock<MockAudioFrameProcessor> audio_frame_processor_;
  FakeTaskQueueFactory task_queue_factory_;

  scoped_refptr<AsyncAudioProcessing::Factory> CreateFactory() {
    return make_ref_counted<AsyncAudioProcessing::Factory>(
        audio_frame_processor_, task_queue_factory_);
  }
};

struct ConfigHelper {
  struct Params {
    bool use_null_audio_processing;
    bool use_async_audio_processing;
  };

  explicit ConfigHelper(const Params& params)
      : audio_mixer(AudioMixerImpl::Create()) {
    audio_state_config.audio_mixer = audio_mixer;
    audio_state_config.audio_processing =
        params.use_null_audio_processing
            ? nullptr
            : make_ref_counted<testing::NiceMock<MockAudioProcessing>>();
    audio_state_config.audio_device_module =
        make_ref_counted<NiceMock<MockAudioDeviceModule>>();
    if (params.use_async_audio_processing) {
      audio_state_config.async_audio_processing_factory =
          async_audio_processing_helper_.CreateFactory();
    }
  }
  AudioState::Config& config() { return audio_state_config; }
  scoped_refptr<AudioMixer> mixer() { return audio_mixer; }
  NiceMock<FakeAsyncAudioProcessingHelper::MockAudioFrameProcessor>&
  mock_audio_frame_processor() {
    return async_audio_processing_helper_.audio_frame_processor_;
  }

 private:
  AudioState::Config audio_state_config;
  scoped_refptr<AudioMixer> audio_mixer;
  FakeAsyncAudioProcessingHelper async_audio_processing_helper_;
};

class FakeAudioSource : public AudioMixer::Source {
 public:
  int Ssrc() const override { return 0; }

  int PreferredSampleRate() const override { return kSampleRate; }

  MOCK_METHOD(AudioFrameInfo,
              GetAudioFrameWithInfo,
              (int sample_rate_hz, AudioFrame*),
              (override));
};

std::vector<int16_t> Create10msTestData(int sample_rate_hz,
                                        size_t num_channels) {
  const int samples_per_channel = sample_rate_hz / 100;
  std::vector<int16_t> audio_data(samples_per_channel * num_channels, 0);
  // Fill the first channel with a 1kHz sine wave.
  const float inc = (2 * std::numbers::pi_v<float> * 1000) / sample_rate_hz;
  float w = 0.f;
  for (int i = 0; i < samples_per_channel; ++i) {
    audio_data[i * num_channels] = static_cast<int16_t>(32767.f * std::sin(w));
    w += inc;
  }
  return audio_data;
}

std::vector<uint32_t> ComputeChannelLevels(AudioFrame* audio_frame) {
  const size_t num_channels = audio_frame->num_channels_;
  const size_t samples_per_channel = audio_frame->samples_per_channel_;
  std::vector<uint32_t> levels(num_channels, 0);
  for (size_t i = 0; i < samples_per_channel; ++i) {
    for (size_t j = 0; j < num_channels; ++j) {
      levels[j] += std::abs(audio_frame->data()[i * num_channels + j]);
    }
  }
  return levels;
}
}  // namespace

class AudioStateTest : public ::testing::TestWithParam<ConfigHelper::Params> {};

TEST_P(AudioStateTest, Create) {
  ConfigHelper helper(GetParam());
  auto audio_state = AudioState::Create(helper.config());
  EXPECT_TRUE(audio_state.get());
}

TEST_P(AudioStateTest, ConstructDestruct) {
  ConfigHelper helper(GetParam());
  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));
}

TEST_P(AudioStateTest, RecordedAudioArrivesAtSingleStream) {
  ConfigHelper helper(GetParam());

  if (GetParam().use_async_audio_processing) {
    EXPECT_CALL(helper.mock_audio_frame_processor(), SinkSet);
    EXPECT_CALL(helper.mock_audio_frame_processor(), ProcessCalled);
    EXPECT_CALL(helper.mock_audio_frame_processor(), SinkCleared);
  }

  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));

  MockAudioSendStream stream;
  audio_state->AddSendingStream(&stream, 8000, 2);

  EXPECT_CALL(
      stream,
      SendAudioDataForMock(::testing::AllOf(
          ::testing::Field(&AudioFrame::sample_rate_hz_, ::testing::Eq(8000)),
          ::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(2u)))))
      .WillOnce(
          // Verify that channels are not swapped by default.
          ::testing::Invoke([](AudioFrame* audio_frame) {
            auto levels = ComputeChannelLevels(audio_frame);
            EXPECT_LT(0u, levels[0]);
            EXPECT_EQ(0u, levels[1]);
          }));
  MockAudioProcessing* ap =
      GetParam().use_null_audio_processing
          ? nullptr
          : static_cast<MockAudioProcessing*>(audio_state->audio_processing());
  if (ap) {
    EXPECT_CALL(*ap, set_stream_delay_ms(0));
    EXPECT_CALL(*ap, set_stream_key_pressed(false));
    EXPECT_CALL(*ap, ProcessStream(_, _, _, Matcher<int16_t*>(_)));
  }

  constexpr size_t kNumChannels = 2;
  auto audio_data = Create10msTestData(kSampleRate, kNumChannels);
  uint32_t new_mic_level = 667;
  audio_state->audio_transport()->RecordedDataIsAvailable(
      &audio_data[0], kSampleRate / 100, kNumChannels * 2, kNumChannels,
      kSampleRate, 0, 0, 0, false, new_mic_level);
  EXPECT_EQ(667u, new_mic_level);

  audio_state->RemoveSendingStream(&stream);
}

TEST_P(AudioStateTest, RecordedAudioArrivesAtMultipleStreams) {
  ConfigHelper helper(GetParam());

  if (GetParam().use_async_audio_processing) {
    EXPECT_CALL(helper.mock_audio_frame_processor(), SinkSet);
    EXPECT_CALL(helper.mock_audio_frame_processor(), ProcessCalled);
    EXPECT_CALL(helper.mock_audio_frame_processor(), SinkCleared);
  }

  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));

  MockAudioSendStream stream_1;
  MockAudioSendStream stream_2;
  audio_state->AddSendingStream(&stream_1, 8001, 2);
  audio_state->AddSendingStream(&stream_2, 32000, 1);

  EXPECT_CALL(
      stream_1,
      SendAudioDataForMock(::testing::AllOf(
          ::testing::Field(&AudioFrame::sample_rate_hz_, ::testing::Eq(16000)),
          ::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(1u)))))
      .WillOnce(
          // Verify that there is output signal.
          ::testing::Invoke([](AudioFrame* audio_frame) {
            auto levels = ComputeChannelLevels(audio_frame);
            EXPECT_LT(0u, levels[0]);
          }));
  EXPECT_CALL(
      stream_2,
      SendAudioDataForMock(::testing::AllOf(
          ::testing::Field(&AudioFrame::sample_rate_hz_, ::testing::Eq(16000)),
          ::testing::Field(&AudioFrame::num_channels_, ::testing::Eq(1u)))))
      .WillOnce(
          // Verify that there is output signal.
          ::testing::Invoke([](AudioFrame* audio_frame) {
            auto levels = ComputeChannelLevels(audio_frame);
            EXPECT_LT(0u, levels[0]);
          }));
  MockAudioProcessing* ap =
      static_cast<MockAudioProcessing*>(audio_state->audio_processing());
  if (ap) {
    EXPECT_CALL(*ap, set_stream_delay_ms(5));
    EXPECT_CALL(*ap, set_stream_key_pressed(true));
    EXPECT_CALL(*ap, ProcessStream(_, _, _, Matcher<int16_t*>(_)));
  }

  constexpr size_t kNumChannels = 1;
  auto audio_data = Create10msTestData(kSampleRate, kNumChannels);
  uint32_t new_mic_level = 667;
  audio_state->audio_transport()->RecordedDataIsAvailable(
      &audio_data[0], kSampleRate / 100, kNumChannels * 2, kNumChannels,
      kSampleRate, 5, 0, 0, true, new_mic_level);
  EXPECT_EQ(667u, new_mic_level);

  audio_state->RemoveSendingStream(&stream_1);
  audio_state->RemoveSendingStream(&stream_2);
}

TEST_P(AudioStateTest, EnableChannelSwap) {
  constexpr size_t kNumChannels = 2;

  ConfigHelper helper(GetParam());

  if (GetParam().use_async_audio_processing) {
    EXPECT_CALL(helper.mock_audio_frame_processor(), SinkSet);
    EXPECT_CALL(helper.mock_audio_frame_processor(), ProcessCalled);
    EXPECT_CALL(helper.mock_audio_frame_processor(), SinkCleared);
  }

  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));

  audio_state->SetStereoChannelSwapping(true);

  MockAudioSendStream stream;
  audio_state->AddSendingStream(&stream, kSampleRate, kNumChannels);

  EXPECT_CALL(stream, SendAudioDataForMock(_))
      .WillOnce(
          // Verify that channels are swapped.
          ::testing::Invoke([](AudioFrame* audio_frame) {
            auto levels = ComputeChannelLevels(audio_frame);
            EXPECT_EQ(0u, levels[0]);
            EXPECT_LT(0u, levels[1]);
          }));

  auto audio_data = Create10msTestData(kSampleRate, kNumChannels);
  uint32_t new_mic_level = 667;
  audio_state->audio_transport()->RecordedDataIsAvailable(
      &audio_data[0], kSampleRate / 100, kNumChannels * 2, kNumChannels,
      kSampleRate, 0, 0, 0, false, new_mic_level);
  EXPECT_EQ(667u, new_mic_level);

  audio_state->RemoveSendingStream(&stream);
}

TEST_P(AudioStateTest,
       QueryingTransportForAudioShouldResultInGetAudioCallOnMixerSource) {
  ConfigHelper helper(GetParam());
  auto audio_state = AudioState::Create(helper.config());

  FakeAudioSource fake_source;
  helper.mixer()->AddSource(&fake_source);

  EXPECT_CALL(fake_source, GetAudioFrameWithInfo(_, _))
      .WillOnce(
          ::testing::Invoke([](int sample_rate_hz, AudioFrame* audio_frame) {
            audio_frame->sample_rate_hz_ = sample_rate_hz;
            audio_frame->samples_per_channel_ = sample_rate_hz / 100;
            audio_frame->num_channels_ = kNumberOfChannels;
            return AudioMixer::Source::AudioFrameInfo::kNormal;
          }));

  int16_t audio_buffer[kSampleRate / 100 * kNumberOfChannels];
  size_t n_samples_out;
  int64_t elapsed_time_ms;
  int64_t ntp_time_ms;
  audio_state->audio_transport()->NeedMorePlayData(
      kSampleRate / 100, kNumberOfChannels * 2, kNumberOfChannels, kSampleRate,
      audio_buffer, n_samples_out, &elapsed_time_ms, &ntp_time_ms);
}

TEST_P(AudioStateTest, StartRecordingDoesNothingWithoutStream) {
  ConfigHelper helper(GetParam());
  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));

  auto* adm = reinterpret_cast<MockAudioDeviceModule*>(
      helper.config().audio_device_module.get());

  EXPECT_CALL(*adm, InitRecording()).Times(0);
  EXPECT_CALL(*adm, StartRecording()).Times(0);
  EXPECT_CALL(*adm, StopRecording()).Times(1);
  audio_state->SetRecording(false);
  audio_state->SetRecording(true);
}

TEST_P(AudioStateTest, AddStreamDoesNothingIfRecordingDisabled) {
  ConfigHelper helper(GetParam());
  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));

  auto* adm = reinterpret_cast<MockAudioDeviceModule*>(
      helper.config().audio_device_module.get());

  EXPECT_CALL(*adm, StopRecording()).Times(2);
  audio_state->SetRecording(false);

  MockAudioSendStream stream;
  EXPECT_CALL(*adm, StartRecording).Times(0);
  audio_state->AddSendingStream(&stream, kSampleRate, kNumberOfChannels);
  audio_state->RemoveSendingStream(&stream);
}

TEST_P(AudioStateTest, AlwaysCallInitRecordingBeforeStartRecording) {
  ConfigHelper helper(GetParam());
  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));

  auto* adm = reinterpret_cast<MockAudioDeviceModule*>(
      helper.config().audio_device_module.get());

  MockAudioSendStream stream;
  {
    InSequence s;
    EXPECT_CALL(*adm, InitRecording());
    EXPECT_CALL(*adm, StartRecording());
    audio_state->AddSendingStream(&stream, kSampleRate, kNumberOfChannels);
  }

  EXPECT_CALL(*adm, StopRecording());
  audio_state->SetRecording(false);

  {
    InSequence s;
    EXPECT_CALL(*adm, InitRecording());
    EXPECT_CALL(*adm, StartRecording());
    audio_state->SetRecording(true);
  }

  EXPECT_CALL(*adm, StopRecording());
  audio_state->RemoveSendingStream(&stream);
}

// The recording can also be initialized by WebRtcVoiceSendChannel
// options_.init_recording_on_send. Make sure StopRecording is still
// being called in this scenario.
TEST_P(AudioStateTest, CallStopRecordingIfRecordingIsInitialized) {
  ConfigHelper helper(GetParam());
  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));

  auto* adm = reinterpret_cast<MockAudioDeviceModule*>(
      helper.config().audio_device_module.get());

  audio_state->SetRecording(false);

  EXPECT_CALL(*adm, StopRecording());
  audio_state->SetRecording(false);
}

TEST_P(AudioStateTest, StartPlayoutDoesNothingWithoutStream) {
  ConfigHelper helper(GetParam());
  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));

  auto* adm = reinterpret_cast<MockAudioDeviceModule*>(
      helper.config().audio_device_module.get());

  EXPECT_CALL(*adm, InitPlayout()).Times(0);
  EXPECT_CALL(*adm, StartPlayout()).Times(0);
  EXPECT_CALL(*adm, StopPlayout()).Times(1);
  audio_state->SetPlayout(false);

  audio_state->SetPlayout(true);
}

TEST_P(AudioStateTest, AlwaysCallInitPlayoutBeforeStartPlayout) {
  ConfigHelper helper(GetParam());
  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));

  auto* adm = reinterpret_cast<MockAudioDeviceModule*>(
      helper.config().audio_device_module.get());

  MockAudioReceiveStream stream;
  {
    InSequence s;
    EXPECT_CALL(*adm, InitPlayout());
    EXPECT_CALL(*adm, StartPlayout());
    audio_state->AddReceivingStream(&stream);
  }

  // SetPlayout(false) starts the NullAudioPoller...which needs a thread.
  ThreadManager::Instance()->WrapCurrentThread();

  EXPECT_CALL(*adm, StopPlayout());
  audio_state->SetPlayout(false);

  {
    InSequence s;
    EXPECT_CALL(*adm, InitPlayout());
    EXPECT_CALL(*adm, StartPlayout());
    audio_state->SetPlayout(true);
  }

  // Playout without streams starts the NullAudioPoller...
  // which needs a thread.
  ThreadManager::Instance()->WrapCurrentThread();

  EXPECT_CALL(*adm, StopPlayout());
  audio_state->RemoveReceivingStream(&stream);
}

TEST_P(AudioStateTest, CallStopPlayoutIfPlayoutIsInitialized) {
  ConfigHelper helper(GetParam());
  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));

  auto* adm = reinterpret_cast<MockAudioDeviceModule*>(
      helper.config().audio_device_module.get());

  audio_state->SetPlayout(false);

  EXPECT_CALL(*adm, StopPlayout());
  audio_state->SetPlayout(false);
}

TEST_P(AudioStateTest, AddStreamDoesNothingIfPlayoutDisabled) {
  ConfigHelper helper(GetParam());
  scoped_refptr<internal::AudioState> audio_state(
      make_ref_counted<internal::AudioState>(helper.config()));

  auto* adm = reinterpret_cast<MockAudioDeviceModule*>(
      helper.config().audio_device_module.get());

  EXPECT_CALL(*adm, StopPlayout()).Times(2);
  audio_state->SetPlayout(false);

  // AddReceivingStream with playout disabled start the NullAudioPoller...
  // which needs a thread.
  ThreadManager::Instance()->WrapCurrentThread();

  MockAudioReceiveStream stream;
  audio_state->AddReceivingStream(&stream);
  audio_state->RemoveReceivingStream(&stream);
}

INSTANTIATE_TEST_SUITE_P(AudioStateTest,
                         AudioStateTest,
                         Values(ConfigHelper::Params({false, false}),
                                ConfigHelper::Params({true, false}),
                                ConfigHelper::Params({false, true}),
                                ConfigHelper::Params({true, true})));

}  // namespace test
}  // namespace webrtc
