/*
 *  Copyright (c) 2018 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_processing/agc2/rnn_vad/symmetric_matrix_buffer.h"

#include "modules/audio_processing/agc2/rnn_vad/ring_buffer.h"
#include "test/gtest.h"

namespace webrtc {
namespace rnn_vad {
namespace test {
namespace {

template <typename T, size_t S>
void CheckSymmetry(const SymmetricMatrixBuffer<T, S>* sym_matrix_buf) {
  for (size_t row = 0; row < S - 1; ++row)
    for (size_t col = row + 1; col < S; ++col)
      EXPECT_EQ(sym_matrix_buf->GetValue(row, col),
                sym_matrix_buf->GetValue(col, row));
}

using PairType = std::pair<int, int>;

// Checks that the symmetric matrix buffer contains any pair with a value equal
// to the given one.
template <size_t S>
bool CheckPairsWithValueExist(
    const SymmetricMatrixBuffer<PairType, S>* sym_matrix_buf,
    const int value) {
  for (size_t row = 0; row < S - 1; ++row) {
    for (size_t col = row + 1; col < S; ++col) {
      auto p = sym_matrix_buf->GetValue(row, col);
      if (p.first == value || p.second == value)
        return true;
    }
  }
  return false;
}

}  // namespace

// Test that shows how to combine RingBuffer and SymmetricMatrixBuffer to
// efficiently compute pair-wise scores. This test verifies that the evolution
// of a SymmetricMatrixBuffer instance follows that of RingBuffer.
TEST(RnnVadTest, SymmetricMatrixBufferUseCase) {
  // Instance a ring buffer which will be fed with a series of integer values.
  constexpr int kRingBufSize = 10;
  RingBuffer<int, 1, static_cast<size_t>(kRingBufSize)> ring_buf;
  // Instance a symmetric matrix buffer for the ring buffer above. It stores
  // pairs of integers with which this test can easily check that the evolution
  // of RingBuffer and SymmetricMatrixBuffer match.
  SymmetricMatrixBuffer<PairType, kRingBufSize> sym_matrix_buf;
  for (int t = 1; t <= 100; ++t) {  // Evolution steps.
    SCOPED_TRACE(t);
    const int t_removed = ring_buf.GetArrayView(kRingBufSize - 1)[0];
    ring_buf.Push({&t, 1});
    // The head of the ring buffer is |t|.
    ASSERT_EQ(t, ring_buf.GetArrayView(0)[0]);
    // Create the comparisons between |t| and the older elements in the ring
    // buffer.
    std::array<PairType, kRingBufSize - 1> new_comparions;
    for (int i = 0; i < kRingBufSize - 1; ++i) {
      // Start comparing |t| to the second newest element in the ring buffer.
      const int delay = i + 1;
      const auto t_prev = ring_buf.GetArrayView(delay)[0];
      ASSERT_EQ(std::max(0, t - delay), t_prev);
      // Compare the last element |t| with |t_prev|.
      new_comparions[i].first = t_prev;
      new_comparions[i].second = t;
    }
    // Push the new comparisons in the symmetric matrix buffer.
    sym_matrix_buf.Push({new_comparions.data(), new_comparions.size()});
    // Tests.
    CheckSymmetry(&sym_matrix_buf);
    // Check that the pairs resulting from the content in the ring buffer are
    // in the right position.
    for (size_t delay1 = 0; delay1 < kRingBufSize - 1; ++delay1) {
      for (size_t delay2 = delay1 + 1; delay2 < kRingBufSize; ++delay2) {
        const auto t1 = ring_buf.GetArrayView(delay1)[0];
        const auto t2 = ring_buf.GetArrayView(delay2)[0];
        ASSERT_LE(t2, t1);
        const auto p = sym_matrix_buf.GetValue(delay1, delay2);
        EXPECT_EQ(p.first, t2);
        EXPECT_EQ(p.second, t1);
      }
    }
    // Check that every older element in the ring buffer still has a
    // corresponding pair in the symmetric matrix buffer.
    for (size_t delay = 1; delay < kRingBufSize; ++delay) {
      const auto t_prev = ring_buf.GetArrayView(delay)[0];
      EXPECT_TRUE(CheckPairsWithValueExist(&sym_matrix_buf, t_prev));
    }
    // Check that the element removed from the ring buffer has no corresponding
    // pairs in the symmetric matrix buffer.
    if (t > kRingBufSize - 1) {
      EXPECT_FALSE(CheckPairsWithValueExist(&sym_matrix_buf, t_removed));
    }
  }
}

}  // namespace test
}  // namespace rnn_vad
}  // namespace webrtc
