/*
 *  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 "rtc_base/numerics/safe_conversions.h"
#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 = rtc::checked_cast<int16_t>(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
