/*
 *  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 "webrtc/modules/audio_coding/neteq/audio_vector.h"

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

#include <string>

#include "testing/gtest/include/gtest/gtest.h"
#include "webrtc/typedefs.h"

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
