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

#include "base/basictypes.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/stringprintf.h"
#include "cobalt/media/base/audio_bus.h"
#include "cobalt/media/base/audio_pull_fifo.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace cobalt {
namespace media {

// Block diagram of a possible real-world usage:
//
//       | Producer | ----> | AudioPullFifo | ----> | Consumer |
//                    push                    pull
//          2048      ---->       (2048)      ---->     ~512

// Number of channels in each audio bus.
static int kChannels = 2;

// Max number of audio framed the FIFO can contain.
static const int kMaxFramesInFifo = 2048;

class AudioPullFifoTest : public testing::TestWithParam<int> {
 public:
  AudioPullFifoTest()
      : pull_fifo_(kChannels, kMaxFramesInFifo,
                   base::Bind(&AudioPullFifoTest::ProvideInput,
                              base::Unretained(this))),
        audio_bus_(AudioBus::Create(kChannels, kMaxFramesInFifo)),
        fill_value_(0),
        last_frame_delay_(-1) {
    EXPECT_EQ(kMaxFramesInFifo, pull_fifo_.SizeInFrames());
  }
  virtual ~AudioPullFifoTest() {}

  void VerifyValue(const float data[], int size, float start_value) {
    float value = start_value;
    for (int i = 0; i < size; ++i) {
      ASSERT_FLOAT_EQ(value++, data[i]) << "i=" << i;
    }
  }

  // Consume data using different sizes, acquire audio frames from the FIFO
  // and verify that the retrieved values matches the values written by the
  // producer.
  void ConsumeTest(int frames_to_consume) {
    int start_value = 0;
    SCOPED_TRACE(
        base::StringPrintf("Checking frames_to_consume %d", frames_to_consume));
    pull_fifo_.Consume(audio_bus_.get(), frames_to_consume);
    for (int j = 0; j < kChannels; ++j) {
      VerifyValue(audio_bus_->channel(j), frames_to_consume, start_value);
    }
    start_value += frames_to_consume;
    EXPECT_LT(last_frame_delay_, audio_bus_->frames());
  }

  // AudioPullFifo::ReadCB implementation where we increase a value for each
  // audio frame that we provide. Note that all channels are given the same
  // value to simplify the verification.
  virtual void ProvideInput(int frame_delay, AudioBus* audio_bus) {
    ASSERT_GT(frame_delay, last_frame_delay_);
    last_frame_delay_ = frame_delay;

    EXPECT_EQ(audio_bus->channels(), audio_bus_->channels());
    EXPECT_EQ(audio_bus->frames(), kMaxFramesInFifo);
    for (int i = 0; i < audio_bus->frames(); ++i) {
      for (int j = 0; j < audio_bus->channels(); ++j) {
        // Store same value in all channels.
        audio_bus->channel(j)[i] = fill_value_;
      }
      fill_value_++;
    }
  }

 protected:
  AudioPullFifo pull_fifo_;
  std::unique_ptr<AudioBus> audio_bus_;
  int fill_value_;
  int last_frame_delay_;

 private:
  DISALLOW_COPY_AND_ASSIGN(AudioPullFifoTest);
};

TEST_P(AudioPullFifoTest, Consume) { ConsumeTest(GetParam()); }

// Test common |frames_to_consume| values which will be used as input
// parameter to AudioPullFifo::Consume() when the consumer asks for data.
INSTANTIATE_TEST_CASE_P(AudioPullFifoTest, AudioPullFifoTest,
                        testing::Values(544, 512, 512, 512, 512, 2048, 544, 441,
                                        440, 433, 500));

}  // namespace media
}  // namespace cobalt
