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