/*
 *  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 <algorithm>
#include <memory>

#include "rtc_base/checks.h"

namespace webrtc {

AudioVector::AudioVector() : AudioVector(kDefaultInitialSize) {
  Clear();
}

AudioVector::AudioVector(size_t initial_size)
    : array_(new int16_t[initial_size + 1]),
      capacity_(initial_size + 1),
      begin_index_(0),
      end_index_(capacity_ - 1) {
  memset(array_.get(), 0, capacity_ * sizeof(int16_t));
}

AudioVector::~AudioVector() = default;

void AudioVector::Clear() {
  end_index_ = begin_index_ = 0;
}

void AudioVector::CopyTo(AudioVector* copy_to) const {
  RTC_DCHECK(copy_to);
  copy_to->Reserve(Size());
  CopyTo(Size(), 0, copy_to->array_.get());
  copy_to->begin_index_ = 0;
  copy_to->end_index_ = Size();
}

void AudioVector::CopyTo(size_t length,
                         size_t position,
                         int16_t* copy_to) const {
  if (length == 0)
    return;
  length = std::min(length, Size() - position);
  const size_t copy_index = (begin_index_ + position) % capacity_;
  const size_t first_chunk_length = std::min(length, capacity_ - copy_index);
  memcpy(copy_to, &array_[copy_index], first_chunk_length * sizeof(int16_t));
  const size_t remaining_length = length - first_chunk_length;
  if (remaining_length > 0) {
    memcpy(&copy_to[first_chunk_length], array_.get(),
           remaining_length * sizeof(int16_t));
  }
}

void AudioVector::PushFront(const AudioVector& prepend_this) {
  const size_t length = prepend_this.Size();
  if (length == 0)
    return;

  // Although the subsequent calling to PushFront does Reserve in it, it is
  // always more efficient to do a big Reserve first.
  Reserve(Size() + length);

  const size_t first_chunk_length =
      std::min(length, prepend_this.capacity_ - prepend_this.begin_index_);
  const size_t remaining_length = length - first_chunk_length;
  if (remaining_length > 0)
    PushFront(prepend_this.array_.get(), remaining_length);
  PushFront(&prepend_this.array_[prepend_this.begin_index_],
            first_chunk_length);
}

void AudioVector::PushFront(const int16_t* prepend_this, size_t length) {
  if (length == 0)
    return;
  Reserve(Size() + length);
  const size_t first_chunk_length = std::min(length, begin_index_);
  memcpy(&array_[begin_index_ - first_chunk_length],
         &prepend_this[length - first_chunk_length],
         first_chunk_length * sizeof(int16_t));
  const size_t remaining_length = length - first_chunk_length;
  if (remaining_length > 0) {
    memcpy(&array_[capacity_ - remaining_length], prepend_this,
           remaining_length * sizeof(int16_t));
  }
  begin_index_ = (begin_index_ + capacity_ - length) % capacity_;
}

void AudioVector::PushBack(const AudioVector& append_this) {
  PushBack(append_this, append_this.Size(), 0);
}

void AudioVector::PushBack(const AudioVector& append_this,
                           size_t length,
                           size_t position) {
  RTC_DCHECK_LE(position, append_this.Size());
  RTC_DCHECK_LE(length, append_this.Size() - position);

  if (length == 0)
    return;

  // Although the subsequent calling to PushBack does Reserve in it, it is
  // always more efficient to do a big Reserve first.
  Reserve(Size() + length);

  const size_t start_index =
      (append_this.begin_index_ + position) % append_this.capacity_;
  const size_t first_chunk_length =
      std::min(length, append_this.capacity_ - start_index);
  PushBack(&append_this.array_[start_index], first_chunk_length);

  const size_t remaining_length = length - first_chunk_length;
  if (remaining_length > 0)
    PushBack(append_this.array_.get(), remaining_length);
}

void AudioVector::PushBack(const int16_t* append_this, size_t length) {
  if (length == 0)
    return;
  Reserve(Size() + length);
  const size_t first_chunk_length = std::min(length, capacity_ - end_index_);
  memcpy(&array_[end_index_], append_this,
         first_chunk_length * sizeof(int16_t));
  const size_t remaining_length = length - first_chunk_length;
  if (remaining_length > 0) {
    memcpy(array_.get(), &append_this[first_chunk_length],
           remaining_length * sizeof(int16_t));
  }
  end_index_ = (end_index_ + length) % capacity_;
}

void AudioVector::PopFront(size_t length) {
  if (length == 0)
    return;
  length = std::min(length, Size());
  begin_index_ = (begin_index_ + length) % capacity_;
}

void AudioVector::PopBack(size_t length) {
  if (length == 0)
    return;
  // Never remove more than what is in the array.
  length = std::min(length, Size());
  end_index_ = (end_index_ + capacity_ - length) % capacity_;
}

void AudioVector::Extend(size_t extra_length) {
  if (extra_length == 0)
    return;
  InsertZerosByPushBack(extra_length, Size());
}

void AudioVector::InsertAt(const int16_t* insert_this,
                           size_t length,
                           size_t position) {
  if (length == 0)
    return;
  // Cap the insert position at the current array length.
  position = std::min(Size(), position);

  // When inserting to a position closer to the beginning, it is more efficient
  // to insert by pushing front than to insert by pushing back, since less data
  // will be moved, vice versa.
  if (position <= Size() - position) {
    InsertByPushFront(insert_this, length, position);
  } else {
    InsertByPushBack(insert_this, length, position);
  }
}

void AudioVector::InsertZerosAt(size_t length, size_t position) {
  if (length == 0)
    return;
  // Cap the insert position at the current array length.
  position = std::min(Size(), position);

  // When inserting to a position closer to the beginning, it is more efficient
  // to insert by pushing front than to insert by pushing back, since less data
  // will be moved, vice versa.
  if (position <= Size() - position) {
    InsertZerosByPushFront(length, position);
  } else {
    InsertZerosByPushBack(length, position);
  }
}

void AudioVector::OverwriteAt(const AudioVector& insert_this,
                              size_t length,
                              size_t position) {
  RTC_DCHECK_LE(length, insert_this.Size());
  if (length == 0)
    return;

  // Cap the insert position at the current array length.
  position = std::min(Size(), position);

  // Although the subsequent calling to OverwriteAt does Reserve in it, it is
  // always more efficient to do a big Reserve first.
  size_t new_size = std::max(Size(), position + length);
  Reserve(new_size);

  const size_t first_chunk_length =
      std::min(length, insert_this.capacity_ - insert_this.begin_index_);
  OverwriteAt(&insert_this.array_[insert_this.begin_index_], first_chunk_length,
              position);
  const size_t remaining_length = length - first_chunk_length;
  if (remaining_length > 0) {
    OverwriteAt(insert_this.array_.get(), remaining_length,
                position + first_chunk_length);
  }
}

void AudioVector::OverwriteAt(const int16_t* insert_this,
                              size_t length,
                              size_t position) {
  if (length == 0)
    return;
  // Cap the insert position at the current array length.
  position = std::min(Size(), position);

  size_t new_size = std::max(Size(), position + length);
  Reserve(new_size);

  const size_t overwrite_index = (begin_index_ + position) % capacity_;
  const size_t first_chunk_length =
      std::min(length, capacity_ - overwrite_index);
  memcpy(&array_[overwrite_index], insert_this,
         first_chunk_length * sizeof(int16_t));
  const size_t remaining_length = length - first_chunk_length;
  if (remaining_length > 0) {
    memcpy(array_.get(), &insert_this[first_chunk_length],
           remaining_length * sizeof(int16_t));
  }

  end_index_ = (begin_index_ + new_size) % capacity_;
}

void AudioVector::CrossFade(const AudioVector& append_this,
                            size_t fade_length) {
  // Fade length cannot be longer than the current vector or |append_this|.
  assert(fade_length <= Size());
  assert(fade_length <= append_this.Size());
  fade_length = std::min(fade_length, Size());
  fade_length = std::min(fade_length, append_this.Size());
  size_t position = Size() - fade_length + begin_index_;
  // Cross fade the overlapping regions.
  // |alpha| is the mixing factor in Q14.
  // TODO(hlundin): Consider skipping +1 in the denominator to produce a
  // smoother cross-fade, in particular at the end of the fade.
  int alpha_step = 16384 / (static_cast<int>(fade_length) + 1);
  int alpha = 16384;
  for (size_t i = 0; i < fade_length; ++i) {
    alpha -= alpha_step;
    array_[(position + i) % capacity_] =
        (alpha * array_[(position + i) % capacity_] +
         (16384 - alpha) * append_this[i] + 8192) >>
        14;
  }
  assert(alpha >= 0);  // Verify that the slope was correct.
  // Append what is left of |append_this|.
  size_t samples_to_push_back = append_this.Size() - fade_length;
  if (samples_to_push_back > 0)
    PushBack(append_this, samples_to_push_back, fade_length);
}

// Returns the number of elements in this AudioVector.
size_t AudioVector::Size() const {
  return (end_index_ + capacity_ - begin_index_) % capacity_;
}

// Returns true if this AudioVector is empty.
bool AudioVector::Empty() const {
  return begin_index_ == end_index_;
}

void AudioVector::Reserve(size_t n) {
  if (capacity_ > n)
    return;
  const size_t length = Size();
  // Reserve one more sample to remove the ambiguity between empty vector and
  // full vector. Therefore |begin_index_| == |end_index_| indicates empty
  // vector, and |begin_index_| == (|end_index_| + 1) % capacity indicates
  // full vector.
  std::unique_ptr<int16_t[]> temp_array(new int16_t[n + 1]);
  CopyTo(length, 0, temp_array.get());
  array_.swap(temp_array);
  begin_index_ = 0;
  end_index_ = length;
  capacity_ = n + 1;
}

void AudioVector::InsertByPushBack(const int16_t* insert_this,
                                   size_t length,
                                   size_t position) {
  const size_t move_chunk_length = Size() - position;
  std::unique_ptr<int16_t[]> temp_array(nullptr);
  if (move_chunk_length > 0) {
    // TODO(minyue): see if it is possible to avoid copying to a buffer.
    temp_array.reset(new int16_t[move_chunk_length]);
    CopyTo(move_chunk_length, position, temp_array.get());
    PopBack(move_chunk_length);
  }

  Reserve(Size() + length + move_chunk_length);
  PushBack(insert_this, length);
  if (move_chunk_length > 0)
    PushBack(temp_array.get(), move_chunk_length);
}

void AudioVector::InsertByPushFront(const int16_t* insert_this,
                                    size_t length,
                                    size_t position) {
  std::unique_ptr<int16_t[]> temp_array(nullptr);
  if (position > 0) {
    // TODO(minyue): see if it is possible to avoid copying to a buffer.
    temp_array.reset(new int16_t[position]);
    CopyTo(position, 0, temp_array.get());
    PopFront(position);
  }

  Reserve(Size() + length + position);
  PushFront(insert_this, length);
  if (position > 0)
    PushFront(temp_array.get(), position);
}

void AudioVector::InsertZerosByPushBack(size_t length, size_t position) {
  const size_t move_chunk_length = Size() - position;
  std::unique_ptr<int16_t[]> temp_array(nullptr);
  if (move_chunk_length > 0) {
    temp_array.reset(new int16_t[move_chunk_length]);
    CopyTo(move_chunk_length, position, temp_array.get());
    PopBack(move_chunk_length);
  }

  Reserve(Size() + length + move_chunk_length);

  const size_t first_zero_chunk_length =
      std::min(length, capacity_ - end_index_);
  memset(&array_[end_index_], 0, first_zero_chunk_length * sizeof(int16_t));
  const size_t remaining_zero_length = length - first_zero_chunk_length;
  if (remaining_zero_length > 0)
    memset(array_.get(), 0, remaining_zero_length * sizeof(int16_t));
  end_index_ = (end_index_ + length) % capacity_;

  if (move_chunk_length > 0)
    PushBack(temp_array.get(), move_chunk_length);
}

void AudioVector::InsertZerosByPushFront(size_t length, size_t position) {
  std::unique_ptr<int16_t[]> temp_array(nullptr);
  if (position > 0) {
    temp_array.reset(new int16_t[position]);
    CopyTo(position, 0, temp_array.get());
    PopFront(position);
  }

  Reserve(Size() + length + position);

  const size_t first_zero_chunk_length = std::min(length, begin_index_);
  memset(&array_[begin_index_ - first_zero_chunk_length], 0,
         first_zero_chunk_length * sizeof(int16_t));
  const size_t remaining_zero_length = length - first_zero_chunk_length;
  if (remaining_zero_length > 0)
    memset(&array_[capacity_ - remaining_zero_length], 0,
           remaining_zero_length * sizeof(int16_t));
  begin_index_ = (begin_index_ + capacity_ - length) % capacity_;

  if (position > 0)
    PushFront(temp_array.get(), position);
}

}  // namespace webrtc
