// Copyright (c) 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.

#include "media/audio/audio_input_device.h"

#include <utility>

#include "base/memory/ptr_util.h"
#include "base/memory/read_only_shared_memory_region.h"
#include "base/process/process_handle.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/sync_socket.h"
#include "base/test/task_environment.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using base::CancelableSyncSocket;
using base::SyncSocket;
using testing::_;
using testing::DoAll;
using testing::Invoke;
using testing::InvokeWithoutArgs;

namespace media {

namespace {

const size_t kMemorySegmentCount = 10u;

class MockAudioInputIPC : public AudioInputIPC {
 public:
  MockAudioInputIPC() = default;
  ~MockAudioInputIPC() override = default;

  MOCK_METHOD4(CreateStream,
               void(AudioInputIPCDelegate* delegate,
                    const AudioParameters& params,
                    bool automatic_gain_control,
                    uint32_t total_segments));
  MOCK_METHOD0(RecordStream, void());
  MOCK_METHOD1(SetVolume, void(double volume));
  MOCK_METHOD1(SetOutputDeviceForAec, void(const std::string&));
  MOCK_METHOD0(CloseStream, void());
};

class MockCaptureCallback : public AudioCapturerSource::CaptureCallback {
 public:
  MockCaptureCallback() = default;
  ~MockCaptureCallback() override = default;

  MOCK_METHOD0(OnCaptureStarted, void());
  MOCK_METHOD4(Capture,
               void(const AudioBus* audio_source,
                    base::TimeTicks audio_capture_time,
                    double volume,
                    bool key_pressed));

  MOCK_METHOD2(OnCaptureError,
               void(AudioCapturerSource::ErrorCode code,
                    const std::string& message));
  MOCK_METHOD1(OnCaptureMuted, void(bool is_muted));
};

}  // namespace.

class AudioInputDeviceTest
    : public ::testing::TestWithParam<AudioInputDevice::DeadStreamDetection> {};

// Regular construction.
TEST_P(AudioInputDeviceTest, Noop) {
  base::test::SingleThreadTaskEnvironment task_environment(
      base::test::SingleThreadTaskEnvironment::MainThreadType::IO);
  MockAudioInputIPC* input_ipc = new MockAudioInputIPC();
  scoped_refptr<AudioInputDevice> device(new AudioInputDevice(
      base::WrapUnique(input_ipc), AudioInputDevice::Purpose::kUserInput,
      AudioInputDeviceTest::GetParam()));
}

ACTION_P(ReportStateChange, device) {
  static_cast<AudioInputIPCDelegate*>(device)->OnError(
      media::AudioCapturerSource::ErrorCode::kUnknown);
}

// Verify that we get an OnCaptureError() callback if CreateStream fails.
TEST_P(AudioInputDeviceTest, FailToCreateStream) {
  AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
                         CHANNEL_LAYOUT_STEREO, 48000, 480);

  MockCaptureCallback callback;
  MockAudioInputIPC* input_ipc = new MockAudioInputIPC();
  scoped_refptr<AudioInputDevice> device(new AudioInputDevice(
      base::WrapUnique(input_ipc), AudioInputDevice::Purpose::kUserInput,
      AudioInputDeviceTest::GetParam()));
  device->Initialize(params, &callback);
  EXPECT_CALL(*input_ipc, CreateStream(_, _, _, _))
      .WillOnce(ReportStateChange(device.get()));
  EXPECT_CALL(callback,
              OnCaptureError(AudioCapturerSource::ErrorCode::kUnknown, _));
  EXPECT_CALL(*input_ipc, CloseStream());
  device->Start();
  device->Stop();
}

TEST_P(AudioInputDeviceTest, CreateStream) {
  AudioParameters params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
                         CHANNEL_LAYOUT_STEREO, 48000, 480);
  base::MappedReadOnlyRegion shared_memory;
  CancelableSyncSocket browser_socket;
  CancelableSyncSocket renderer_socket;

  const uint32_t memory_size =
      media::ComputeAudioInputBufferSize(params, kMemorySegmentCount);

  shared_memory = base::ReadOnlySharedMemoryRegion::Create(memory_size);
  ASSERT_TRUE(shared_memory.IsValid());
  memset(shared_memory.mapping.memory(), 0xff, memory_size);

  ASSERT_TRUE(
      CancelableSyncSocket::CreatePair(&browser_socket, &renderer_socket));
  base::ReadOnlySharedMemoryRegion duplicated_shared_memory_region =
      shared_memory.region.Duplicate();
  ASSERT_TRUE(duplicated_shared_memory_region.IsValid());

  base::test::TaskEnvironment ste;
  MockCaptureCallback callback;
  MockAudioInputIPC* input_ipc = new MockAudioInputIPC();
  scoped_refptr<AudioInputDevice> device(new AudioInputDevice(
      base::WrapUnique(input_ipc), AudioInputDevice::Purpose::kUserInput,
      AudioInputDeviceTest::GetParam()));
  device->Initialize(params, &callback);

  EXPECT_CALL(*input_ipc, CreateStream(_, _, _, _))
      .WillOnce(InvokeWithoutArgs([&]() {
        static_cast<AudioInputIPCDelegate*>(device.get())
            ->OnStreamCreated(std::move(duplicated_shared_memory_region),
                              renderer_socket.Take(), false);
      }));
  EXPECT_CALL(*input_ipc, RecordStream());

  EXPECT_CALL(callback, OnCaptureStarted());
  device->Start();
  EXPECT_CALL(*input_ipc, CloseStream());
  device->Stop();
}

INSTANTIATE_TEST_SUITE_P(
    AudioInputDeviceGroup,
    AudioInputDeviceTest,
    ::testing::Values(AudioInputDevice::DeadStreamDetection::kDisabled,
                      AudioInputDevice::DeadStreamDetection::kEnabled));

}  // namespace media.
