/*
 *  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_vector.h"

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

#include <string>

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

namespace webrtc {

class AudioVectorTest : public ::testing::Test {
 protected:
  virtual void SetUp() {
    // Populate test array.
    for (size_t i = 0; i < array_length(); ++i) {
      array_[i] = i;
    }
  }

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

  int16_t array_[10];
};

// Create and destroy AudioVector objects, both empty and with a predefined
// length.
TEST_F(AudioVectorTest, CreateAndDestroy) {
  AudioVector vec1;
  EXPECT_TRUE(vec1.Empty());
  EXPECT_EQ(0u, vec1.Size());

  size_t initial_size = 17;
  AudioVector vec2(initial_size);
  EXPECT_FALSE(vec2.Empty());
  EXPECT_EQ(initial_size, vec2.Size());
}

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

// Test the PushBack method and the CopyFrom method. The Clear method is also
// invoked.
TEST_F(AudioVectorTest, PushBackAndCopy) {
  AudioVector vec;
  AudioVector vec_copy;
  vec.PushBack(array_, array_length());
  vec.CopyTo(&vec_copy);  // Copy from |vec| to |vec_copy|.
  ASSERT_EQ(array_length(), vec.Size());
  ASSERT_EQ(array_length(), vec_copy.Size());
  for (size_t i = 0; i < array_length(); ++i) {
    EXPECT_EQ(array_[i], vec[i]);
    EXPECT_EQ(array_[i], vec_copy[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());
}

// Test the PushBack method with another AudioVector as input argument.
TEST_F(AudioVectorTest, PushBackVector) {
  static const size_t kLength = 10;
  AudioVector vec1(kLength);
  AudioVector vec2(kLength);
  // Set the first vector to [0, 1, ..., kLength - 1].
  // Set the second vector to [kLength, kLength + 1, ..., 2 * kLength - 1].
  for (size_t i = 0; i < kLength; ++i) {
    vec1[i] = static_cast<int16_t>(i);
    vec2[i] = static_cast<int16_t>(i + kLength);
  }
  // Append vec2 to the back of vec1.
  vec1.PushBack(vec2);
  ASSERT_EQ(2 * kLength, vec1.Size());
  for (size_t i = 0; i < 2 * kLength; ++i) {
    EXPECT_EQ(static_cast<int16_t>(i), vec1[i]);
  }
}

// Test the PushFront method.
TEST_F(AudioVectorTest, PushFront) {
  AudioVector vec;
  vec.PushFront(array_, array_length());
  ASSERT_EQ(array_length(), vec.Size());
  for (size_t i = 0; i < array_length(); ++i) {
    EXPECT_EQ(array_[i], vec[i]);
  }
}

// Test the PushFront method with another AudioVector as input argument.
TEST_F(AudioVectorTest, PushFrontVector) {
  static const size_t kLength = 10;
  AudioVector vec1(kLength);
  AudioVector vec2(kLength);
  // Set the first vector to [0, 1, ..., kLength - 1].
  // Set the second vector to [kLength, kLength + 1, ..., 2 * kLength - 1].
  for (size_t i = 0; i < kLength; ++i) {
    vec1[i] = static_cast<int16_t>(i);
    vec2[i] = static_cast<int16_t>(i + kLength);
  }
  // Prepend vec1 to the front of vec2.
  vec2.PushFront(vec1);
  ASSERT_EQ(2 * kLength, vec2.Size());
  for (size_t i = 0; i < 2 * kLength; ++i) {
    EXPECT_EQ(static_cast<int16_t>(i), vec2[i]);
  }
}

// Test the PopFront method.
TEST_F(AudioVectorTest, PopFront) {
  AudioVector vec;
  vec.PushBack(array_, array_length());
  vec.PopFront(1);  // Remove one element.
  EXPECT_EQ(array_length() - 1u, vec.Size());
  for (size_t i = 0; i < array_length() - 1; ++i) {
    EXPECT_EQ(static_cast<int16_t>(i + 1), vec[i]);
  }
  vec.PopFront(array_length());  // Remove more elements than vector size.
  EXPECT_EQ(0u, vec.Size());
}

// Test the PopBack method.
TEST_F(AudioVectorTest, PopBack) {
  AudioVector vec;
  vec.PushBack(array_, array_length());
  vec.PopBack(1);  // Remove one element.
  EXPECT_EQ(array_length() - 1u, vec.Size());
  for (size_t i = 0; i < array_length() - 1; ++i) {
    EXPECT_EQ(static_cast<int16_t>(i), vec[i]);
  }
  vec.PopBack(array_length());  // Remove more elements than vector size.
  EXPECT_EQ(0u, vec.Size());
}

// Test the Extend method.
TEST_F(AudioVectorTest, Extend) {
  AudioVector vec;
  vec.PushBack(array_, array_length());
  vec.Extend(5);  // Extend with 5 elements, which should all be zeros.
  ASSERT_EQ(array_length() + 5u, vec.Size());
  // Verify that all are zero.
  for (size_t i = array_length(); i < array_length() + 5; ++i) {
    EXPECT_EQ(0, vec[i]);
  }
}

// Test the InsertAt method with an insert position in the middle of the vector.
TEST_F(AudioVectorTest, InsertAt) {
  AudioVector vec;
  vec.PushBack(array_, array_length());
  static const int kNewLength = 5;
  int16_t new_array[kNewLength];
  // Set array elements to {100, 101, 102, ... }.
  for (int i = 0; i < kNewLength; ++i) {
    new_array[i] = 100 + i;
  }
  int insert_position = 5;
  vec.InsertAt(new_array, kNewLength, insert_position);
  // Verify that the vector looks as follows:
  // {0, 1, ..., |insert_position| - 1, 100, 101, ..., 100 + kNewLength - 1,
  //  |insert_position|, |insert_position| + 1, ..., kLength - 1}.
  size_t pos = 0;
  for (int i = 0; i < insert_position; ++i) {
    EXPECT_EQ(array_[i], vec[pos]);
    ++pos;
  }
  for (int i = 0; i < kNewLength; ++i) {
    EXPECT_EQ(new_array[i], vec[pos]);
    ++pos;
  }
  for (size_t i = insert_position; i < array_length(); ++i) {
    EXPECT_EQ(array_[i], vec[pos]);
    ++pos;
  }
}

// Test the InsertZerosAt method with an insert position in the middle of the
// vector. Use the InsertAt method as reference.
TEST_F(AudioVectorTest, InsertZerosAt) {
  AudioVector vec;
  AudioVector vec_ref;
  vec.PushBack(array_, array_length());
  vec_ref.PushBack(array_, array_length());
  static const int kNewLength = 5;
  int insert_position = 5;
  vec.InsertZerosAt(kNewLength, insert_position);
  int16_t new_array[kNewLength] = {0};  // All zero elements.
  vec_ref.InsertAt(new_array, kNewLength, insert_position);
  // Verify that the vectors are identical.
  ASSERT_EQ(vec_ref.Size(), vec.Size());
  for (size_t i = 0; i < vec.Size(); ++i) {
    EXPECT_EQ(vec_ref[i], vec[i]);
  }
}

// Test the InsertAt method with an insert position at the start of the vector.
TEST_F(AudioVectorTest, InsertAtBeginning) {
  AudioVector vec;
  vec.PushBack(array_, array_length());
  static const int kNewLength = 5;
  int16_t new_array[kNewLength];
  // Set array elements to {100, 101, 102, ... }.
  for (int i = 0; i < kNewLength; ++i) {
    new_array[i] = 100 + i;
  }
  int insert_position = 0;
  vec.InsertAt(new_array, kNewLength, insert_position);
  // Verify that the vector looks as follows:
  // {100, 101, ..., 100 + kNewLength - 1,
  //  0, 1, ..., kLength - 1}.
  size_t pos = 0;
  for (int i = 0; i < kNewLength; ++i) {
    EXPECT_EQ(new_array[i], vec[pos]);
    ++pos;
  }
  for (size_t i = insert_position; i < array_length(); ++i) {
    EXPECT_EQ(array_[i], vec[pos]);
    ++pos;
  }
}

// Test the InsertAt method with an insert position at the end of the vector.
TEST_F(AudioVectorTest, InsertAtEnd) {
  AudioVector vec;
  vec.PushBack(array_, array_length());
  static const int kNewLength = 5;
  int16_t new_array[kNewLength];
  // Set array elements to {100, 101, 102, ... }.
  for (int i = 0; i < kNewLength; ++i) {
    new_array[i] = 100 + i;
  }
  int insert_position = array_length();
  vec.InsertAt(new_array, kNewLength, insert_position);
  // Verify that the vector looks as follows:
  // {0, 1, ..., kLength - 1, 100, 101, ..., 100 + kNewLength - 1 }.
  size_t pos = 0;
  for (size_t i = 0; i < array_length(); ++i) {
    EXPECT_EQ(array_[i], vec[pos]);
    ++pos;
  }
  for (int i = 0; i < kNewLength; ++i) {
    EXPECT_EQ(new_array[i], vec[pos]);
    ++pos;
  }
}

// Test the InsertAt method with an insert position beyond the end of the
// vector. Verify that a position beyond the end of the vector does not lead to
// an error. The expected outcome is the same as if the vector end was used as
// input position. That is, the input position should be capped at the maximum
// allowed value.
TEST_F(AudioVectorTest, InsertBeyondEnd) {
  AudioVector vec;
  vec.PushBack(array_, array_length());
  static const int kNewLength = 5;
  int16_t new_array[kNewLength];
  // Set array elements to {100, 101, 102, ... }.
  for (int i = 0; i < kNewLength; ++i) {
    new_array[i] = 100 + i;
  }
  int insert_position = array_length() + 10;  // Too large.
  vec.InsertAt(new_array, kNewLength, insert_position);
  // Verify that the vector looks as follows:
  // {0, 1, ..., kLength - 1, 100, 101, ..., 100 + kNewLength - 1 }.
  size_t pos = 0;
  for (size_t i = 0; i < array_length(); ++i) {
    EXPECT_EQ(array_[i], vec[pos]);
    ++pos;
  }
  for (int i = 0; i < kNewLength; ++i) {
    EXPECT_EQ(new_array[i], vec[pos]);
    ++pos;
  }
}

// Test the OverwriteAt method with a position such that all of the new values
// fit within the old vector.
TEST_F(AudioVectorTest, OverwriteAt) {
  AudioVector vec;
  vec.PushBack(array_, array_length());
  static const int kNewLength = 5;
  int16_t new_array[kNewLength];
  // Set array elements to {100, 101, 102, ... }.
  for (int i = 0; i < kNewLength; ++i) {
    new_array[i] = 100 + i;
  }
  size_t insert_position = 2;
  vec.OverwriteAt(new_array, kNewLength, insert_position);
  // Verify that the vector looks as follows:
  // {0, ..., |insert_position| - 1, 100, 101, ..., 100 + kNewLength - 1,
  //  |insert_position|, |insert_position| + 1, ..., kLength - 1}.
  size_t pos = 0;
  for (pos = 0; pos < insert_position; ++pos) {
    EXPECT_EQ(array_[pos], vec[pos]);
  }
  for (int i = 0; i < kNewLength; ++i) {
    EXPECT_EQ(new_array[i], vec[pos]);
    ++pos;
  }
  for (; pos < array_length(); ++pos) {
    EXPECT_EQ(array_[pos], vec[pos]);
  }
}

// Test the OverwriteAt method with a position such that some of the new values
// extend beyond the end of the current vector. This is valid, and the vector is
// expected to expand to accommodate the new values.
TEST_F(AudioVectorTest, OverwriteBeyondEnd) {
  AudioVector vec;
  vec.PushBack(array_, array_length());
  static const int kNewLength = 5;
  int16_t new_array[kNewLength];
  // Set array elements to {100, 101, 102, ... }.
  for (int i = 0; i < kNewLength; ++i) {
    new_array[i] = 100 + i;
  }
  int insert_position = array_length() - 2;
  vec.OverwriteAt(new_array, kNewLength, insert_position);
  ASSERT_EQ(array_length() - 2u + kNewLength, vec.Size());
  // Verify that the vector looks as follows:
  // {0, ..., |insert_position| - 1, 100, 101, ..., 100 + kNewLength - 1,
  //  |insert_position|, |insert_position| + 1, ..., kLength - 1}.
  int pos = 0;
  for (pos = 0; pos < insert_position; ++pos) {
    EXPECT_EQ(array_[pos], vec[pos]);
  }
  for (int i = 0; i < kNewLength; ++i) {
    EXPECT_EQ(new_array[i], vec[pos]);
    ++pos;
  }
  // Verify that we checked to the end of |vec|.
  EXPECT_EQ(vec.Size(), static_cast<size_t>(pos));
}

TEST_F(AudioVectorTest, CrossFade) {
  static const size_t kLength = 100;
  static const size_t kFadeLength = 10;
  AudioVector vec1(kLength);
  AudioVector vec2(kLength);
  // Set all vector elements to 0 in |vec1| and 100 in |vec2|.
  for (size_t i = 0; i < kLength; ++i) {
    vec1[i] = 0;
    vec2[i] = 100;
  }
  vec1.CrossFade(vec2, kFadeLength);
  ASSERT_EQ(2 * kLength - kFadeLength, vec1.Size());
  // First part untouched.
  for (size_t i = 0; i < kLength - kFadeLength; ++i) {
    EXPECT_EQ(0, vec1[i]);
  }
  // Check mixing zone.
  for (size_t i = 0 ; i < kFadeLength; ++i) {
    EXPECT_NEAR((i + 1) * 100 / (kFadeLength + 1),
                vec1[kLength - kFadeLength + i], 1);
  }
  // Second part untouched.
  for (size_t i = kLength; i < vec1.Size(); ++i) {
    EXPECT_EQ(100, vec1[i]);
  }
}

}  // namespace webrtc
