// 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.

#include "media/audio/audio_debug_recording_helper.h"

#include <limits>
#include <memory>
#include <utility>

#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/memory/ptr_util.h"
#include "base/run_loop.h"
#include "base/single_thread_task_runner.h"
#include "base/test/scoped_task_environment.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_sample_types.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::_;
using testing::Return;

namespace media {

namespace {

const base::FilePath::CharType kFileName[] =
    FILE_PATH_LITERAL("debug_recording.output.1.wav");

}  // namespace

// Mock class for the audio file writer that the helper wraps.
class MockAudioDebugFileWriter : public AudioDebugFileWriter {
 public:
  explicit MockAudioDebugFileWriter(const AudioParameters& params)
      : AudioDebugFileWriter(params), reference_data_(nullptr) {}
  ~MockAudioDebugFileWriter() override = default;

  MOCK_METHOD1(DoStart, void(bool));
  void Start(base::File file) override { DoStart(file.IsValid()); }
  MOCK_METHOD0(Stop, void());

  // Functions with move-only types as arguments can't be mocked directly, so
  // we pass on to DoWrite(). Also, we can verify the data this way.
  MOCK_METHOD1(DoWrite, void(AudioBus*));
  void Write(std::unique_ptr<AudioBus> data) override {
    CHECK(reference_data_);
    EXPECT_EQ(reference_data_->channels(), data->channels());
    EXPECT_EQ(reference_data_->frames(), data->frames());
    for (int i = 0; i < data->channels(); ++i) {
      float* data_ptr = data->channel(i);
      float* ref_data_ptr = reference_data_->channel(i);
      for (int j = 0; j < data->frames(); ++j, ++data_ptr, ++ref_data_ptr)
        EXPECT_EQ(*ref_data_ptr, *data_ptr);
    }
    DoWrite(data.get());
  }

  MOCK_METHOD0(WillWrite, bool());

  // Set reference data to compare against. Must be called before Write() is
  // called.
  void SetReferenceData(AudioBus* reference_data) {
    EXPECT_EQ(params_.channels(), reference_data->channels());
    EXPECT_EQ(params_.frames_per_buffer(), reference_data->frames());
    reference_data_ = reference_data;
  }

 private:
  AudioBus* reference_data_;

  DISALLOW_COPY_AND_ASSIGN(MockAudioDebugFileWriter);
};

// Sub-class of the helper that overrides the CreateAudioDebugFileWriter
// function to create the above mock instead.
class AudioDebugRecordingHelperUnderTest : public AudioDebugRecordingHelper {
 public:
  AudioDebugRecordingHelperUnderTest(
      const AudioParameters& params,
      scoped_refptr<base::SingleThreadTaskRunner> task_runner,
      base::OnceClosure on_destruction_closure)
      : AudioDebugRecordingHelper(params,
                                  std::move(task_runner),
                                  std::move(on_destruction_closure)) {}
  ~AudioDebugRecordingHelperUnderTest() override = default;

 private:
  // Creates the mock writer. After the mock writer is returned, we always
  // expect Start() to be called on it by the helper.
  std::unique_ptr<AudioDebugFileWriter> CreateAudioDebugFileWriter(
      const AudioParameters& params) override {
    MockAudioDebugFileWriter* writer = new MockAudioDebugFileWriter(params);
    EXPECT_CALL(*writer, DoStart(true));
    return base::WrapUnique<AudioDebugFileWriter>(writer);
  }

  DISALLOW_COPY_AND_ASSIGN(AudioDebugRecordingHelperUnderTest);
};

class AudioDebugRecordingHelperTest : public ::testing::Test {
 public:
  AudioDebugRecordingHelperTest() {}
  ~AudioDebugRecordingHelperTest() override = default;

  // Helper function that creates a recording helper.
  std::unique_ptr<AudioDebugRecordingHelper> CreateRecordingHelper(
      const AudioParameters& params,
      base::OnceClosure on_destruction_closure) {
    return std::make_unique<AudioDebugRecordingHelperUnderTest>(
        params, scoped_task_environment_.GetMainThreadTaskRunner(),
        std::move(on_destruction_closure));
  }

  MOCK_METHOD0(OnAudioDebugRecordingHelperDestruction, void());

  // Bound and passed to AudioDebugRecordingHelper::EnableDebugRecording as
  // AudioDebugRecordingHelper::CreateWavFileCallback.
  void CreateWavFile(AudioDebugRecordingStreamType stream_type,
                     uint32_t id,
                     base::OnceCallback<void(base::File)> reply_callback) {
    // Check that AudioDebugRecordingHelper::EnableDebugRecording calls
    // CreateWavFileCallback with expected stream type and id.
    EXPECT_EQ(stream_type_, stream_type);
    EXPECT_EQ(id_, id);
    base::ScopedTempDir temp_dir;
    ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    base::FilePath path(temp_dir.GetPath().Append(base::FilePath(kFileName)));
    base::File debug_file(
        path, base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE);
    // Run |reply_callback| with a valid file for expected
    // MockAudioDebugFileWriter::Start mocked call to happen.
    std::move(reply_callback).Run(std::move(debug_file));
    // File can be removed right away because MockAudioDebugFileWriter::Start is
    // called synchronously.
    ASSERT_TRUE(base::DeleteFile(path, false));
  }

 protected:
  const AudioDebugRecordingStreamType stream_type_ =
      AudioDebugRecordingStreamType::kInput;
  const uint32_t id_ = 1;

  // The test task environment.
  base::test::ScopedTaskEnvironment scoped_task_environment_;

 private:
  DISALLOW_COPY_AND_ASSIGN(AudioDebugRecordingHelperTest);
};

// Creates a helper with an on destruction closure, and verifies that it's run.
TEST_F(AudioDebugRecordingHelperTest, TestDestructionClosure) {
  const AudioParameters params;
  std::unique_ptr<AudioDebugRecordingHelper> recording_helper =
      CreateRecordingHelper(
          params, base::BindOnce(&AudioDebugRecordingHelperTest::
                                     OnAudioDebugRecordingHelperDestruction,
                                 base::Unretained(this)));

  EXPECT_CALL(*this, OnAudioDebugRecordingHelperDestruction());
}

// Verifies that disable can be called without being enabled.
TEST_F(AudioDebugRecordingHelperTest, OnlyDisable) {
  const AudioParameters params;
  std::unique_ptr<AudioDebugRecordingHelper> recording_helper =
      CreateRecordingHelper(params, base::OnceClosure());

  recording_helper->DisableDebugRecording();
}

TEST_F(AudioDebugRecordingHelperTest, EnableDisable) {
  const AudioParameters params;
  std::unique_ptr<AudioDebugRecordingHelper> recording_helper =
      CreateRecordingHelper(params, base::OnceClosure());

  recording_helper->EnableDebugRecording(
      stream_type_, id_,
      base::BindOnce(&AudioDebugRecordingHelperTest::CreateWavFile,
                     base::Unretained(this)));
  EXPECT_CALL(*static_cast<MockAudioDebugFileWriter*>(
                  recording_helper->debug_writer_.get()),
              Stop());
  recording_helper->DisableDebugRecording();

  recording_helper->EnableDebugRecording(
      stream_type_, id_,
      base::BindOnce(&AudioDebugRecordingHelperTest::CreateWavFile,
                     base::Unretained(this)));
  EXPECT_CALL(*static_cast<MockAudioDebugFileWriter*>(
                  recording_helper->debug_writer_.get()),
              Stop());
  recording_helper->DisableDebugRecording();
}

TEST_F(AudioDebugRecordingHelperTest, OnData) {
  // Only channel layout and frames per buffer is used in the file writer and
  // AudioBus, the other parameters are ignored.
  const int number_of_frames = 100;
  const AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR,
                               ChannelLayout::CHANNEL_LAYOUT_STEREO, 0,
                               number_of_frames);

  // Setup some data.
  const int number_of_samples = number_of_frames * params.channels();
  const float step = std::numeric_limits<int16_t>::max() / number_of_frames;
  std::unique_ptr<float[]> source_data(new float[number_of_samples]);
  for (float i = 0; i < number_of_samples; ++i)
    source_data[i] = i * step;
  std::unique_ptr<AudioBus> audio_bus = AudioBus::Create(params);
  audio_bus->FromInterleaved<Float32SampleTypeTraits>(source_data.get(),
                                                      number_of_frames);

  std::unique_ptr<AudioDebugRecordingHelper> recording_helper =
      CreateRecordingHelper(params, base::OnceClosure());

  // Should not do anything.
  recording_helper->OnData(audio_bus.get());

  recording_helper->EnableDebugRecording(
      stream_type_, id_,
      base::BindOnce(&AudioDebugRecordingHelperTest::CreateWavFile,
                     base::Unretained(this)));
  MockAudioDebugFileWriter* mock_audio_file_writer =
      static_cast<MockAudioDebugFileWriter*>(
          recording_helper->debug_writer_.get());
  mock_audio_file_writer->SetReferenceData(audio_bus.get());

  EXPECT_CALL(*mock_audio_file_writer, DoWrite(_));
  recording_helper->OnData(audio_bus.get());
  base::RunLoop().RunUntilIdle();

  EXPECT_CALL(*mock_audio_file_writer, Stop());
  recording_helper->DisableDebugRecording();

  // Make sure we clear the loop before enabling again.
  base::RunLoop().RunUntilIdle();

  // Enable again, this time with two OnData() calls, one OnData() call without
  // running the message loop until after disabling, and one call after
  // disabling.
  recording_helper->EnableDebugRecording(
      stream_type_, id_,
      base::BindOnce(&AudioDebugRecordingHelperTest::CreateWavFile,
                     base::Unretained(this)));
  mock_audio_file_writer = static_cast<MockAudioDebugFileWriter*>(
      recording_helper->debug_writer_.get());
  mock_audio_file_writer->SetReferenceData(audio_bus.get());

  EXPECT_CALL(*mock_audio_file_writer, DoWrite(_)).Times(2);
  recording_helper->OnData(audio_bus.get());
  recording_helper->OnData(audio_bus.get());
  base::RunLoop().RunUntilIdle();

  // This call should not yield a DoWrite() call on the mock, since the message
  // loop isn't run until after disabling. WillWrite() is expected since
  // recording is enabled.
  recording_helper->OnData(audio_bus.get());

  EXPECT_CALL(*mock_audio_file_writer, Stop());
  recording_helper->DisableDebugRecording();

  // This call should not yield a DoWrite() call on the mock either.
  recording_helper->OnData(audio_bus.get());
  base::RunLoop().RunUntilIdle();
}

}  // namespace media
