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

#include "webrtc/rtc_base/checks.h"
#include "webrtc/typedefs.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
