/*
 *  Copyright (c) 2013 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/fine_audio_buffer.h"

#include <limits.h>
#include <memory>

#include "api/array_view.h"
#include "api/task_queue/default_task_queue_factory.h"
#include "modules/audio_device/mock_audio_device_buffer.h"
#include "test/gmock.h"
#include "test/gtest.h"

using ::testing::_;
using ::testing::AtLeast;
using ::testing::InSequence;
using ::testing::Return;

namespace webrtc {

const int kSampleRate = 44100;
const int kChannels = 2;
const int kSamplesPer10Ms = kSampleRate * 10 / 1000;

// The fake audio data is 0,1,..SCHAR_MAX-1,0,1,... This is to make it easy
// to detect errors. This function verifies that the buffers contain such data.
// E.g. if there are two buffers of size 3, buffer 1 would contain 0,1,2 and
// buffer 2 would contain 3,4,5. Note that SCHAR_MAX is 127 so wrap-around
// will happen.
// |buffer| is the audio buffer to verify.
bool VerifyBuffer(const int16_t* buffer, int buffer_number, int size) {
  int start_value = (buffer_number * size) % SCHAR_MAX;
  for (int i = 0; i < size; ++i) {
    if (buffer[i] != (i + start_value) % SCHAR_MAX) {
      return false;
    }
  }
  return true;
}

// This function replaces the real AudioDeviceBuffer::GetPlayoutData when it's
// called (which is done implicitly when calling GetBufferData). It writes the
// sequence 0,1,..SCHAR_MAX-1,0,1,... to the buffer. Note that this is likely a
// buffer of different size than the one VerifyBuffer verifies.
// |iteration| is the number of calls made to UpdateBuffer prior to this call.
// |samples_per_10_ms| is the number of samples that should be written to the
// buffer (|arg0|).
ACTION_P2(UpdateBuffer, iteration, samples_per_10_ms) {
  int16_t* buffer = static_cast<int16_t*>(arg0);
  int start_value = (iteration * samples_per_10_ms) % SCHAR_MAX;
  for (int i = 0; i < samples_per_10_ms; ++i) {
    buffer[i] = (i + start_value) % SCHAR_MAX;
  }
  // Should return samples per channel.
  return samples_per_10_ms / kChannels;
}

// Writes a periodic ramp pattern to the supplied |buffer|. See UpdateBuffer()
// for details.
void UpdateInputBuffer(int16_t* buffer, int iteration, int size) {
  int start_value = (iteration * size) % SCHAR_MAX;
  for (int i = 0; i < size; ++i) {
    buffer[i] = (i + start_value) % SCHAR_MAX;
  }
}

// Action macro which verifies that the recorded 10ms chunk of audio data
// (in |arg0|) contains the correct reference values even if they have been
// supplied using a buffer size that is smaller or larger than 10ms.
// See VerifyBuffer() for details.
ACTION_P2(VerifyInputBuffer, iteration, samples_per_10_ms) {
  const int16_t* buffer = static_cast<const int16_t*>(arg0);
  int start_value = (iteration * samples_per_10_ms) % SCHAR_MAX;
  for (int i = 0; i < samples_per_10_ms; ++i) {
    EXPECT_EQ(buffer[i], (i + start_value) % SCHAR_MAX);
  }
  return 0;
}

void RunFineBufferTest(int frame_size_in_samples) {
  const int kFrameSizeSamples = frame_size_in_samples;
  const int kNumberOfFrames = 5;
  // Ceiling of integer division: 1 + ((x - 1) / y)
  const int kNumberOfUpdateBufferCalls =
      1 + ((kNumberOfFrames * frame_size_in_samples - 1) / kSamplesPer10Ms);

  auto task_queue_factory = CreateDefaultTaskQueueFactory();
  MockAudioDeviceBuffer audio_device_buffer(task_queue_factory.get());
  audio_device_buffer.SetPlayoutSampleRate(kSampleRate);
  audio_device_buffer.SetPlayoutChannels(kChannels);
  audio_device_buffer.SetRecordingSampleRate(kSampleRate);
  audio_device_buffer.SetRecordingChannels(kChannels);

  EXPECT_CALL(audio_device_buffer, RequestPlayoutData(_))
      .WillRepeatedly(Return(kSamplesPer10Ms));
  {
    InSequence s;
    for (int i = 0; i < kNumberOfUpdateBufferCalls; ++i) {
      EXPECT_CALL(audio_device_buffer, GetPlayoutData(_))
          .WillOnce(UpdateBuffer(i, kChannels * kSamplesPer10Ms))
          .RetiresOnSaturation();
    }
  }
  {
    InSequence s;
    for (int j = 0; j < kNumberOfUpdateBufferCalls - 1; ++j) {
      EXPECT_CALL(audio_device_buffer, SetRecordedBuffer(_, kSamplesPer10Ms))
          .WillOnce(VerifyInputBuffer(j, kChannels * kSamplesPer10Ms))
          .RetiresOnSaturation();
    }
  }
  EXPECT_CALL(audio_device_buffer, SetVQEData(_, _))
      .Times(kNumberOfUpdateBufferCalls - 1);
  EXPECT_CALL(audio_device_buffer, DeliverRecordedData())
      .Times(kNumberOfUpdateBufferCalls - 1)
      .WillRepeatedly(Return(0));

  FineAudioBuffer fine_buffer(&audio_device_buffer);
  std::unique_ptr<int16_t[]> out_buffer(
      new int16_t[kChannels * kFrameSizeSamples]);
  std::unique_ptr<int16_t[]> in_buffer(
      new int16_t[kChannels * kFrameSizeSamples]);

  for (int i = 0; i < kNumberOfFrames; ++i) {
    fine_buffer.GetPlayoutData(
        rtc::ArrayView<int16_t>(out_buffer.get(),
                                kChannels * kFrameSizeSamples),
        0);
    EXPECT_TRUE(
        VerifyBuffer(out_buffer.get(), i, kChannels * kFrameSizeSamples));
    UpdateInputBuffer(in_buffer.get(), i, kChannels * kFrameSizeSamples);
    fine_buffer.DeliverRecordedData(
        rtc::ArrayView<const int16_t>(in_buffer.get(),
                                      kChannels * kFrameSizeSamples),
        0);
  }
}

TEST(FineBufferTest, BufferLessThan10ms) {
  const int kFrameSizeSamples = kSamplesPer10Ms - 50;
  RunFineBufferTest(kFrameSizeSamples);
}

TEST(FineBufferTest, GreaterThan10ms) {
  const int kFrameSizeSamples = kSamplesPer10Ms + 50;
  RunFineBufferTest(kFrameSizeSamples);
}

}  // namespace webrtc
