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

#include "base/logging.h"
#include "base/macros.h"
#include "media/base/audio_bus.h"
#include "media/base/audio_hash.h"
#include "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;
static const int kSampleRate = 48000;

class AudioHashTest : public testing::Test {
 public:
  AudioHashTest()
      : bus_one_(AudioBus::Create(kChannelCount, kFrameCount)),
        bus_two_(AudioBus::Create(kChannelCount, kFrameCount)),
        fake_callback_(0.01, kSampleRate) {
    // 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(base::TimeDelta(), base::TimeTicks::Now(), 0,
                            wrapped_bus.get());
    }
  }

  ~AudioHashTest() override = default;

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

  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
