// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_AUDIO_AUDIO_SYSTEM_TEST_UTIL_H_
#define MEDIA_AUDIO_AUDIO_SYSTEM_TEST_UTIL_H_

#include "base/bind.h"
#include "base/location.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/threading/thread_checker.h"
#include "media/audio/audio_device_description.h"
#include "media/audio/audio_system.h"
#include "media/audio/mock_audio_manager.h"
#include "media/base/audio_parameters.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "third_party/abseil-cpp/absl/types/optional.h"

namespace media {

// For tests only. Creates AudioSystem callbacks to be passed to AudioSystem
// methods. When AudioSystem calls such a callback, it verifies treading
// expectations and checks recieved parameters against expected values passed
// during its creation. After that it calls |on_cb_received| closure.
// Note AudioSystemCallbackExpectations object must outlive all the callbacks
// it produced, since they contain raw pointers to it.
class AudioSystemCallbackExpectations {
 public:
  AudioSystemCallbackExpectations() = default;
  AudioSystem::OnAudioParamsCallback GetAudioParamsCallback(
      const base::Location& location,
      base::OnceClosure on_cb_received,
      const absl::optional<AudioParameters>& expected_params);

  AudioSystem::OnBoolCallback GetBoolCallback(const base::Location& location,
                                              base::OnceClosure on_cb_received,
                                              bool expected);

  AudioSystem::OnDeviceDescriptionsCallback GetDeviceDescriptionsCallback(
      const base::Location& location,
      base::OnceClosure on_cb_received,
      const AudioDeviceDescriptions& expected_descriptions);

  AudioSystem::OnInputDeviceInfoCallback GetInputDeviceInfoCallback(
      const base::Location& location,
      base::OnceClosure on_cb_received,
      const absl::optional<AudioParameters>& expected_input,
      const absl::optional<std::string>& expected_associated_device_id);

  AudioSystem::OnDeviceIdCallback GetDeviceIdCallback(
      const base::Location& location,
      base::OnceClosure on_cb_received,
      const absl::optional<std::string>& expected_id);

 private:
  // Methods to verify correctness of received data.
  void OnAudioParams(const std::string& from_here,
                     base::OnceClosure on_cb_received,
                     const absl::optional<AudioParameters>& expected,
                     const absl::optional<AudioParameters>& received);

  void OnBool(const std::string& from_here,
              base::OnceClosure on_cb_received,
              bool expected,
              bool result);

  void OnDeviceDescriptions(
      const std::string& from_here,
      base::OnceClosure on_cb_received,
      const AudioDeviceDescriptions& expected_descriptions,
      AudioDeviceDescriptions descriptions);

  void OnInputDeviceInfo(
      const std::string& from_here,
      base::OnceClosure on_cb_received,
      const absl::optional<AudioParameters>& expected_input,
      const absl::optional<std::string>& expected_associated_device_id,
      const absl::optional<AudioParameters>& input,
      const absl::optional<std::string>& associated_device_id);

  void OnDeviceId(const std::string& from_here,
                  base::OnceClosure on_cb_received,
                  const absl::optional<std::string>& expected_id,
                  const absl::optional<std::string>& result_id);

  THREAD_CHECKER(thread_checker_);
  DISALLOW_COPY_AND_ASSIGN(AudioSystemCallbackExpectations);
};

// Template test case to test AudioSystem implementations.
template <class T>
class AudioSystemTestTemplate : public T {
 public:
  AudioSystemTestTemplate() {}

  AudioSystemTestTemplate(const AudioSystemTestTemplate&) = delete;
  AudioSystemTestTemplate& operator=(const AudioSystemTestTemplate&) = delete;

  ~AudioSystemTestTemplate() override {}

  void SetUp() override {
    T::SetUp();
    input_params_ =
        AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
                        AudioParameters::kTelephoneSampleRate,
                        AudioParameters::kTelephoneSampleRate / 10);
    output_params_ =
        AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
                        AudioParameters::kTelephoneSampleRate,
                        AudioParameters::kTelephoneSampleRate / 20);
    default_output_params_ =
        AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO,
                        AudioParameters::kTelephoneSampleRate,
                        AudioParameters::kTelephoneSampleRate / 30);
    audio_manager()->SetInputStreamParameters(input_params_);
    audio_manager()->SetOutputStreamParameters(output_params_);
    audio_manager()->SetDefaultOutputStreamParameters(default_output_params_);

    auto get_device_descriptions = [](const AudioDeviceDescriptions* source,
                                      AudioDeviceDescriptions* destination) {
      destination->insert(destination->end(), source->begin(), source->end());
    };

    audio_manager()->SetInputDeviceDescriptionsCallback(
        base::BindRepeating(get_device_descriptions,
                            base::Unretained(&input_device_descriptions_)));
    audio_manager()->SetOutputDeviceDescriptionsCallback(
        base::BindRepeating(get_device_descriptions,
                            base::Unretained(&output_device_descriptions_)));
  }

 protected:
  MockAudioManager* audio_manager() { return T::audio_manager(); }
  AudioSystem* audio_system() { return T::audio_system(); }

  AudioSystemCallbackExpectations expectations_;
  AudioParameters input_params_;
  AudioParameters output_params_;
  AudioParameters default_output_params_;
  AudioDeviceDescriptions input_device_descriptions_;
  AudioDeviceDescriptions output_device_descriptions_;
};

TYPED_TEST_SUITE_P(AudioSystemTestTemplate);

TYPED_TEST_P(AudioSystemTestTemplate, GetInputStreamParametersNormal) {
  base::RunLoop wait_loop;
  this->audio_system()->GetInputStreamParameters(
      AudioDeviceDescription::kDefaultDeviceId,
      this->expectations_.GetAudioParamsCallback(
          FROM_HERE, wait_loop.QuitClosure(), this->input_params_));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, GetInputStreamParametersNoDevice) {
  this->audio_manager()->SetHasInputDevices(false);

  base::RunLoop wait_loop;
  this->audio_system()->GetInputStreamParameters(
      AudioDeviceDescription::kDefaultDeviceId,
      this->expectations_.GetAudioParamsCallback(
          FROM_HERE, wait_loop.QuitClosure(),
          absl::optional<AudioParameters>()));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, GetOutputStreamParameters) {
  base::RunLoop wait_loop;
  this->audio_system()->GetOutputStreamParameters(
      "non-default-device-id",
      this->expectations_.GetAudioParamsCallback(
          FROM_HERE, wait_loop.QuitClosure(), this->output_params_));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, GetDefaultOutputStreamParameters) {
  base::RunLoop wait_loop;
  this->audio_system()->GetOutputStreamParameters(
      AudioDeviceDescription::kDefaultDeviceId,
      this->expectations_.GetAudioParamsCallback(
          FROM_HERE, wait_loop.QuitClosure(), this->default_output_params_));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate,
             GetOutputStreamParametersForDefaultDeviceNoDevices) {
  this->audio_manager()->SetHasOutputDevices(false);
  base::RunLoop wait_loop;
  this->audio_system()->GetOutputStreamParameters(
      AudioDeviceDescription::kDefaultDeviceId,
      this->expectations_.GetAudioParamsCallback(
          FROM_HERE, wait_loop.QuitClosure(),
          absl::optional<AudioParameters>()));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate,
             GetOutputStreamParametersForNonDefaultDeviceNoDevices) {
  this->audio_manager()->SetHasOutputDevices(false);
  base::RunLoop wait_loop;
  this->audio_system()->GetOutputStreamParameters(
      "non-default-device-id", this->expectations_.GetAudioParamsCallback(
                                   FROM_HERE, wait_loop.QuitClosure(),
                                   absl::optional<AudioParameters>()));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, HasInputDevices) {
  base::RunLoop wait_loop;
  this->audio_system()->HasInputDevices(this->expectations_.GetBoolCallback(
      FROM_HERE, wait_loop.QuitClosure(), true));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, HasNoInputDevices) {
  this->audio_manager()->SetHasInputDevices(false);
  base::RunLoop wait_loop;
  this->audio_system()->HasInputDevices(this->expectations_.GetBoolCallback(
      FROM_HERE, wait_loop.QuitClosure(), false));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, HasOutputDevices) {
  base::RunLoop wait_loop;
  this->audio_system()->HasOutputDevices(this->expectations_.GetBoolCallback(
      FROM_HERE, wait_loop.QuitClosure(), true));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, HasNoOutputDevices) {
  this->audio_manager()->SetHasOutputDevices(false);
  base::RunLoop wait_loop;
  this->audio_system()->HasOutputDevices(this->expectations_.GetBoolCallback(
      FROM_HERE, wait_loop.QuitClosure(), false));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate,
             GetInputDeviceDescriptionsNoInputDevices) {
  this->output_device_descriptions_.emplace_back(
      "output_device_name", "output_device_id", "group_id");
  EXPECT_EQ(0, static_cast<int>(this->input_device_descriptions_.size()));
  EXPECT_EQ(1, static_cast<int>(this->output_device_descriptions_.size()));

  base::RunLoop wait_loop;
  this->audio_system()->GetDeviceDescriptions(
      true, this->expectations_.GetDeviceDescriptionsCallback(
                FROM_HERE, wait_loop.QuitClosure(),
                this->input_device_descriptions_));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, GetInputDeviceDescriptions) {
  this->output_device_descriptions_.emplace_back(
      "output_device_name", "output_device_id", "group_id");
  this->input_device_descriptions_.emplace_back(
      "input_device_name1", "input_device_id1", "group_id1");
  this->input_device_descriptions_.emplace_back(
      "input_device_name2", "input_device_id2", "group_id2");
  EXPECT_EQ(2, static_cast<int>(this->input_device_descriptions_.size()));
  EXPECT_EQ(1, static_cast<int>(this->output_device_descriptions_.size()));

  base::RunLoop wait_loop;
  this->audio_system()->GetDeviceDescriptions(
      true, this->expectations_.GetDeviceDescriptionsCallback(
                FROM_HERE, wait_loop.QuitClosure(),
                this->input_device_descriptions_));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate,
             GetOutputDeviceDescriptionsNoInputDevices) {
  this->input_device_descriptions_.emplace_back("input_device_name",
                                                "input_device_id", "group_id");
  EXPECT_EQ(0, static_cast<int>(this->output_device_descriptions_.size()));
  EXPECT_EQ(1, static_cast<int>(this->input_device_descriptions_.size()));

  base::RunLoop wait_loop;
  this->audio_system()->GetDeviceDescriptions(
      false, this->expectations_.GetDeviceDescriptionsCallback(
                 FROM_HERE, wait_loop.QuitClosure(),
                 this->output_device_descriptions_));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, GetOutputDeviceDescriptions) {
  this->input_device_descriptions_.emplace_back("input_device_name",
                                                "input_device_id", "group_id");
  this->output_device_descriptions_.emplace_back(
      "output_device_name1", "output_device_id1", "group_id1");
  this->output_device_descriptions_.emplace_back(
      "output_device_name2", "output_device_id2", "group_id2");
  EXPECT_EQ(2, static_cast<int>(this->output_device_descriptions_.size()));
  EXPECT_EQ(1, static_cast<int>(this->input_device_descriptions_.size()));

  base::RunLoop wait_loop;
  this->audio_system()->GetDeviceDescriptions(
      false, this->expectations_.GetDeviceDescriptionsCallback(
                 FROM_HERE, wait_loop.QuitClosure(),
                 this->output_device_descriptions_));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, GetAssociatedOutputDeviceID) {
  const std::string associated_id("associated_id");
  this->audio_manager()->SetAssociatedOutputDeviceIDCallback(
      base::BindRepeating([](const std::string& result, const std::string&)
                              -> std::string { return result; },
                          associated_id));

  base::RunLoop wait_loop;
  this->audio_system()->GetAssociatedOutputDeviceID(
      std::string(), this->expectations_.GetDeviceIdCallback(
                         FROM_HERE, wait_loop.QuitClosure(), associated_id));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, GetInputDeviceInfoNoAssociation) {
  base::RunLoop wait_loop;
  this->audio_system()->GetInputDeviceInfo(
      "non-default-device-id",
      this->expectations_.GetInputDeviceInfoCallback(
          FROM_HERE, wait_loop.QuitClosure(), this->input_params_,
          absl::optional<std::string>()));
  wait_loop.Run();
}

TYPED_TEST_P(AudioSystemTestTemplate, GetInputDeviceInfoWithAssociation) {
  const std::string associated_id("associated_id");
  this->audio_manager()->SetAssociatedOutputDeviceIDCallback(
      base::BindRepeating([](const std::string& result, const std::string&)
                              -> std::string { return result; },
                          associated_id));

  base::RunLoop wait_loop;
  this->audio_system()->GetInputDeviceInfo(
      "non-default-device-id", this->expectations_.GetInputDeviceInfoCallback(
                                   FROM_HERE, wait_loop.QuitClosure(),
                                   this->input_params_, associated_id));
  wait_loop.Run();
}

REGISTER_TYPED_TEST_SUITE_P(
    AudioSystemTestTemplate,
    GetInputStreamParametersNormal,
    GetInputStreamParametersNoDevice,
    GetOutputStreamParameters,
    GetDefaultOutputStreamParameters,
    GetOutputStreamParametersForDefaultDeviceNoDevices,
    GetOutputStreamParametersForNonDefaultDeviceNoDevices,
    HasInputDevices,
    HasNoInputDevices,
    HasOutputDevices,
    HasNoOutputDevices,
    GetInputDeviceDescriptionsNoInputDevices,
    GetInputDeviceDescriptions,
    GetOutputDeviceDescriptionsNoInputDevices,
    GetOutputDeviceDescriptions,
    GetAssociatedOutputDeviceID,
    GetInputDeviceInfoNoAssociation,
    GetInputDeviceInfoWithAssociation);

}  // namespace media

#endif  // MEDIA_AUDIO_AUDIO_SYSTEM_TEST_UTIL_H_
