/*
 *  Copyright (c) 2012 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_coding/neteq/audio_multi_vector.h"

#include <assert.h>
#include <stdlib.h>

#include <string>

#include "test/gtest.h"
#include "typedefs.h"  // NOLINT(build/include)

namespace webrtc {

// This is a value-parameterized test. The test cases are instantiated with
// different values for the test parameter, which is used to determine the
// number of channels in the AudioMultiBuffer. Note that it is not possible
// to combine typed testing with value-parameterized testing, and since the
// tests for AudioVector already covers a number of different type parameters,
// this test focuses on testing different number of channels, and keeping the
// value type constant.

class AudioMultiVectorTest : public ::testing::TestWithParam<size_t> {
 protected:
  AudioMultiVectorTest()
      : num_channels_(GetParam()),  // Get the test parameter.
        interleaved_length_(num_channels_ * array_length()) {
    array_interleaved_ = new int16_t[num_channels_ * array_length()];
  }

  ~AudioMultiVectorTest() {
    delete [] array_interleaved_;
  }

  virtual void SetUp() {
    // Populate test arrays.
    for (size_t i = 0; i < array_length(); ++i) {
      array_[i] = static_cast<int16_t>(i);
    }
    int16_t* ptr = array_interleaved_;
    // Write 100, 101, 102, ... for first channel.
    // Write 200, 201, 202, ... for second channel.
    // And so on.
    for (size_t i = 0; i < array_length(); ++i) {
      for (size_t j = 1; j <= num_channels_; ++j) {
        *ptr = j * 100 + i;
        ++ptr;
      }
    }
  }

  size_t array_length() const {
    return sizeof(array_) / sizeof(array_[0]);
  }

  const size_t num_channels_;
  size_t interleaved_length_;
  int16_t array_[10];
  int16_t* array_interleaved_;
};

// Create and destroy AudioMultiVector objects, both empty and with a predefined
// length.
TEST_P(AudioMultiVectorTest, CreateAndDestroy) {
  AudioMultiVector vec1(num_channels_);
  EXPECT_TRUE(vec1.Empty());
  EXPECT_EQ(num_channels_, vec1.Channels());
  EXPECT_EQ(0u, vec1.Size());

  size_t initial_size = 17;
  AudioMultiVector vec2(num_channels_, initial_size);
  EXPECT_FALSE(vec2.Empty());
  EXPECT_EQ(num_channels_, vec2.Channels());
  EXPECT_EQ(initial_size, vec2.Size());
}

// Test the subscript operator [] for getting and setting.
TEST_P(AudioMultiVectorTest, SubscriptOperator) {
  AudioMultiVector vec(num_channels_, array_length());
  for (size_t channel = 0; channel < num_channels_; ++channel) {
    for (size_t i = 0; i < array_length(); ++i) {
      vec[channel][i] = static_cast<int16_t>(i);
      // Make sure to use the const version.
      const AudioVector& audio_vec = vec[channel];
      EXPECT_EQ(static_cast<int16_t>(i), audio_vec[i]);
    }
  }
}

// Test the PushBackInterleaved method and the CopyFrom method. The Clear
// method is also invoked.
TEST_P(AudioMultiVectorTest, PushBackInterleavedAndCopy) {
  AudioMultiVector vec(num_channels_);
  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
  AudioMultiVector vec_copy(num_channels_);
  vec.CopyTo(&vec_copy);  // Copy from |vec| to |vec_copy|.
  ASSERT_EQ(num_channels_, vec.Channels());
  ASSERT_EQ(array_length(), vec.Size());
  ASSERT_EQ(num_channels_, vec_copy.Channels());
  ASSERT_EQ(array_length(), vec_copy.Size());
  for (size_t channel = 0; channel < vec.Channels(); ++channel) {
    for (size_t i = 0; i < array_length(); ++i) {
      EXPECT_EQ(static_cast<int16_t>((channel + 1) * 100 + i), vec[channel][i]);
      EXPECT_EQ(vec[channel][i], vec_copy[channel][i]);
    }
  }

  // Clear |vec| and verify that it is empty.
  vec.Clear();
  EXPECT_TRUE(vec.Empty());

  // Now copy the empty vector and verify that the copy becomes empty too.
  vec.CopyTo(&vec_copy);
  EXPECT_TRUE(vec_copy.Empty());
}

// Try to copy to a NULL pointer. Nothing should happen.
TEST_P(AudioMultiVectorTest, CopyToNull) {
  AudioMultiVector vec(num_channels_);
  AudioMultiVector* vec_copy = NULL;
  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
  vec.CopyTo(vec_copy);
}

// Test the PushBack method with another AudioMultiVector as input argument.
TEST_P(AudioMultiVectorTest, PushBackVector) {
  AudioMultiVector vec1(num_channels_, array_length());
  AudioMultiVector vec2(num_channels_, array_length());
  // Set the first vector to [0, 1, ..., array_length() - 1] +
  //   100 * channel_number.
  // Set the second vector to [array_length(), array_length() + 1, ...,
  //   2 * array_length() - 1] + 100 * channel_number.
  for (size_t channel = 0; channel < num_channels_; ++channel) {
    for (size_t i = 0; i < array_length(); ++i) {
      vec1[channel][i] = static_cast<int16_t>(i + 100 * channel);
      vec2[channel][i] =
          static_cast<int16_t>(i + 100 * channel + array_length());
    }
  }
  // Append vec2 to the back of vec1.
  vec1.PushBack(vec2);
  ASSERT_EQ(2u * array_length(), vec1.Size());
  for (size_t channel = 0; channel < num_channels_; ++channel) {
    for (size_t i = 0; i < 2 * array_length(); ++i) {
      EXPECT_EQ(static_cast<int16_t>(i + 100 * channel), vec1[channel][i]);
    }
  }
}

// Test the PushBackFromIndex method.
TEST_P(AudioMultiVectorTest, PushBackFromIndex) {
  AudioMultiVector vec1(num_channels_);
  vec1.PushBackInterleaved(array_interleaved_, interleaved_length_);
  AudioMultiVector vec2(num_channels_);

  // Append vec1 to the back of vec2 (which is empty). Read vec1 from the second
  // last element.
  vec2.PushBackFromIndex(vec1, array_length() - 2);
  ASSERT_EQ(2u, vec2.Size());
  for (size_t channel = 0; channel < num_channels_; ++channel) {
    for (size_t i = 0; i < 2; ++i) {
      EXPECT_EQ(array_interleaved_[channel + num_channels_ *
                  (array_length() - 2 + i)], vec2[channel][i]);
    }
  }
}

// Starts with pushing some values to the vector, then test the Zeros method.
TEST_P(AudioMultiVectorTest, Zeros) {
  AudioMultiVector vec(num_channels_);
  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
  vec.Zeros(2 * array_length());
  ASSERT_EQ(num_channels_, vec.Channels());
  ASSERT_EQ(2u * array_length(), vec.Size());
  for (size_t channel = 0; channel < num_channels_; ++channel) {
    for (size_t i = 0; i < 2 * array_length(); ++i) {
      EXPECT_EQ(0, vec[channel][i]);
    }
  }
}

// Test the ReadInterleaved method
TEST_P(AudioMultiVectorTest, ReadInterleaved) {
  AudioMultiVector vec(num_channels_);
  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
  int16_t* output = new int16_t[interleaved_length_];
  // Read 5 samples.
  size_t read_samples = 5;
  EXPECT_EQ(num_channels_ * read_samples,
            vec.ReadInterleaved(read_samples, output));
  EXPECT_EQ(0,
            memcmp(array_interleaved_, output, read_samples * sizeof(int16_t)));

  // Read too many samples. Expect to get all samples from the vector.
  EXPECT_EQ(interleaved_length_,
            vec.ReadInterleaved(array_length() + 1, output));
  EXPECT_EQ(0,
            memcmp(array_interleaved_, output, read_samples * sizeof(int16_t)));

  delete [] output;
}

// Test the PopFront method.
TEST_P(AudioMultiVectorTest, PopFront) {
  AudioMultiVector vec(num_channels_);
  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
  vec.PopFront(1);  // Remove one element from each channel.
  ASSERT_EQ(array_length() - 1u, vec.Size());
  // Let |ptr| point to the second element of the first channel in the
  // interleaved array.
  int16_t* ptr = &array_interleaved_[num_channels_];
  for (size_t i = 0; i < array_length() - 1; ++i) {
    for (size_t channel = 0; channel < num_channels_; ++channel) {
      EXPECT_EQ(*ptr, vec[channel][i]);
      ++ptr;
    }
  }
  vec.PopFront(array_length());  // Remove more elements than vector size.
  EXPECT_EQ(0u, vec.Size());
}

// Test the PopBack method.
TEST_P(AudioMultiVectorTest, PopBack) {
  AudioMultiVector vec(num_channels_);
  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
  vec.PopBack(1);  // Remove one element from each channel.
  ASSERT_EQ(array_length() - 1u, vec.Size());
  // Let |ptr| point to the first element of the first channel in the
  // interleaved array.
  int16_t* ptr = array_interleaved_;
  for (size_t i = 0; i < array_length() - 1; ++i) {
    for (size_t channel = 0; channel < num_channels_; ++channel) {
      EXPECT_EQ(*ptr, vec[channel][i]);
      ++ptr;
    }
  }
  vec.PopBack(array_length());  // Remove more elements than vector size.
  EXPECT_EQ(0u, vec.Size());
}

// Test the AssertSize method.
TEST_P(AudioMultiVectorTest, AssertSize) {
  AudioMultiVector vec(num_channels_, array_length());
  EXPECT_EQ(array_length(), vec.Size());
  // Start with asserting with smaller sizes than already allocated.
  vec.AssertSize(0);
  vec.AssertSize(array_length() - 1);
  // Nothing should have changed.
  EXPECT_EQ(array_length(), vec.Size());
  // Assert with one element longer than already allocated.
  vec.AssertSize(array_length() + 1);
  // Expect vector to have grown.
  EXPECT_EQ(array_length() + 1, vec.Size());
  // Also check the individual AudioVectors.
  for (size_t channel = 0; channel < vec.Channels(); ++channel) {
    EXPECT_EQ(array_length() + 1u, vec[channel].Size());
  }
}

// Test the PushBack method with another AudioMultiVector as input argument.
TEST_P(AudioMultiVectorTest, OverwriteAt) {
  AudioMultiVector vec1(num_channels_);
  vec1.PushBackInterleaved(array_interleaved_, interleaved_length_);
  AudioMultiVector vec2(num_channels_);
  vec2.Zeros(3);  // 3 zeros in each channel.
  // Overwrite vec2 at position 5.
  vec1.OverwriteAt(vec2, 3, 5);
  // Verify result.
  // Length remains the same.
  ASSERT_EQ(array_length(), vec1.Size());
  int16_t* ptr = array_interleaved_;
  for (size_t i = 0; i < array_length() - 1; ++i) {
    for (size_t channel = 0; channel < num_channels_; ++channel) {
      if (i >= 5 && i <= 7) {
        // Elements 5, 6, 7 should have been replaced with zeros.
        EXPECT_EQ(0, vec1[channel][i]);
      } else {
        EXPECT_EQ(*ptr, vec1[channel][i]);
      }
      ++ptr;
    }
  }
}

// Test the CopyChannel method, when the test is instantiated with at least two
// channels.
TEST_P(AudioMultiVectorTest, CopyChannel) {
  if (num_channels_ < 2)
    return;

  AudioMultiVector vec(num_channels_);
  vec.PushBackInterleaved(array_interleaved_, interleaved_length_);
  // Create a reference copy.
  AudioMultiVector ref(num_channels_);
  ref.PushBack(vec);
  // Copy from first to last channel.
  vec.CopyChannel(0, num_channels_ - 1);
  // Verify that the first and last channels are identical; the others should
  // be left untouched.
  for (size_t i = 0; i < array_length(); ++i) {
    // Verify that all but the last channel are untouched.
    for (size_t channel = 0; channel < num_channels_ - 1; ++channel) {
      EXPECT_EQ(ref[channel][i], vec[channel][i]);
    }
    // Verify that the last and the first channels are identical.
    EXPECT_EQ(vec[0][i], vec[num_channels_ - 1][i]);
  }
}

INSTANTIATE_TEST_CASE_P(TestNumChannels,
                        AudioMultiVectorTest,
                        ::testing::Values(static_cast<size_t>(1),
                                          static_cast<size_t>(2),
                                          static_cast<size_t>(5)));
}  // namespace webrtc
