// Copyright 2013 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 <algorithm>
#include <memory>

#include "base/basictypes.h"
#include "base/logging.h"
#include "cobalt/media/base/audio_bus.h"
#include "cobalt/media/base/audio_hash.h"
#include "cobalt/media/base/fake_audio_render_callback.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace media {

static const int kChannelCount = 2;
static const int kFrameCount = 1024;

class AudioHashTest : public testing::Test {
 public:
  AudioHashTest()
      : bus_one_(AudioBus::Create(kChannelCount, kFrameCount)),
        bus_two_(AudioBus::Create(kChannelCount, kFrameCount)),
        fake_callback_(0.01) {
    // Fill each channel in each bus with unique data.
    GenerateUniqueChannels(bus_one_.get());
    GenerateUniqueChannels(bus_two_.get());
  }

  void GenerateUniqueChannels(AudioBus* audio_bus) {
    // Use an AudioBus wrapper to avoid an extra memcpy when filling channels.
    std::unique_ptr<AudioBus> wrapped_bus = AudioBus::CreateWrapper(1);
    wrapped_bus->set_frames(audio_bus->frames());

    // Since FakeAudioRenderCallback generates only a single channel of unique
    // audio data, we need to fill each channel manually.
    for (int ch = 0; ch < audio_bus->channels(); ++ch) {
      wrapped_bus->SetChannelData(0, audio_bus->channel(ch));
      fake_callback_.Render(wrapped_bus.get(), 0, 0);
    }
  }

  ~AudioHashTest() override {}

 protected:
  std::unique_ptr<AudioBus> bus_one_;
  std::unique_ptr<AudioBus> bus_two_;
  FakeAudioRenderCallback fake_callback_;

 private:
  DISALLOW_COPY_AND_ASSIGN(AudioHashTest);
};

// Ensure the same data hashes the same.
TEST_F(AudioHashTest, Equivalence) {
  AudioHash hash_one;
  hash_one.Update(bus_one_.get(), bus_one_->frames());

  AudioHash hash_two;
  hash_two.Update(bus_one_.get(), bus_one_->frames());

  EXPECT_EQ(hash_one.ToString(), hash_two.ToString());
}

// Ensure sample order matters to the hash.
TEST_F(AudioHashTest, SampleOrder) {
  AudioHash original_hash;
  original_hash.Update(bus_one_.get(), bus_one_->frames());

  // Swap a sample in the bus.
  std::swap(bus_one_->channel(0)[0], bus_one_->channel(0)[1]);

  AudioHash swapped_hash;
  swapped_hash.Update(bus_one_.get(), bus_one_->frames());

  EXPECT_NE(original_hash.ToString(), swapped_hash.ToString());
}

// Ensure channel order matters to the hash.
TEST_F(AudioHashTest, ChannelOrder) {
  AudioHash original_hash;
  original_hash.Update(bus_one_.get(), bus_one_->frames());

  // Reverse channel order for the same sample data.
  const int channels = bus_one_->channels();
  std::unique_ptr<AudioBus> swapped_ch_bus = AudioBus::CreateWrapper(channels);
  swapped_ch_bus->set_frames(bus_one_->frames());
  for (int i = channels - 1; i >= 0; --i)
    swapped_ch_bus->SetChannelData(channels - (i + 1), bus_one_->channel(i));

  AudioHash swapped_hash;
  swapped_hash.Update(swapped_ch_bus.get(), swapped_ch_bus->frames());

  EXPECT_NE(original_hash.ToString(), swapped_hash.ToString());
}

// Ensure bus order matters to the hash.
TEST_F(AudioHashTest, BusOrder) {
  AudioHash original_hash;
  original_hash.Update(bus_one_.get(), bus_one_->frames());
  original_hash.Update(bus_two_.get(), bus_two_->frames());

  AudioHash reordered_hash;
  reordered_hash.Update(bus_two_.get(), bus_two_->frames());
  reordered_hash.Update(bus_one_.get(), bus_one_->frames());

  EXPECT_NE(original_hash.ToString(), reordered_hash.ToString());
}

// Ensure bus order matters to the hash even with empty buses.
TEST_F(AudioHashTest, EmptyBusOrder) {
  bus_one_->Zero();
  bus_two_->Zero();

  AudioHash one_bus_hash;
  one_bus_hash.Update(bus_one_.get(), bus_one_->frames());

  AudioHash two_bus_hash;
  two_bus_hash.Update(bus_one_.get(), bus_one_->frames());
  two_bus_hash.Update(bus_two_.get(), bus_two_->frames());

  EXPECT_NE(one_bus_hash.ToString(), two_bus_hash.ToString());
}

// Where A = [0, n], ensure hash(A[0:n/2]), hash(A[n/2:n]) and hash(A) result
// in the same value.
TEST_F(AudioHashTest, HashIgnoresUpdateOrder) {
  AudioHash full_hash;
  full_hash.Update(bus_one_.get(), bus_one_->frames());

  AudioHash half_hash;
  half_hash.Update(bus_one_.get(), bus_one_->frames() / 2);

  // Create a new bus representing the second half of |bus_one_|.
  const int half_frames = bus_one_->frames() / 2;
  const int channels = bus_one_->channels();
  std::unique_ptr<AudioBus> half_bus = AudioBus::CreateWrapper(channels);
  half_bus->set_frames(half_frames);
  for (int i = 0; i < channels; ++i)
    half_bus->SetChannelData(i, bus_one_->channel(i) + half_frames);

  half_hash.Update(half_bus.get(), half_bus->frames());
  EXPECT_EQ(full_hash.ToString(), half_hash.ToString());
}

// Ensure approximate hashes pass verification.
TEST_F(AudioHashTest, VerifySimilarHash) {
  AudioHash hash_one;
  hash_one.Update(bus_one_.get(), bus_one_->frames());

  // Twiddle the values inside the first bus.
  float* channel = bus_one_->channel(0);
  for (int i = 0; i < bus_one_->frames(); i += bus_one_->frames() / 64)
    channel[i] += 0.0001f;

  AudioHash hash_two;
  hash_two.Update(bus_one_.get(), bus_one_->frames());

  EXPECT_EQ(hash_one.ToString(), hash_two.ToString());

  // Twiddle the values too much...
  for (int i = 0; i < bus_one_->frames(); ++i) channel[i] += 0.0001f;

  AudioHash hash_three;
  hash_three.Update(bus_one_.get(), bus_one_->frames());
  EXPECT_NE(hash_one.ToString(), hash_three.ToString());
}

}  // namespace media
