/*
 *  Copyright 2020 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 "rtc_base/callback_list.h"

#include <cstddef>

#include "api/function_view.h"
#include "rtc_base/checks.h"
#include "rtc_base/untyped_function.h"

namespace webrtc {
namespace callback_list_impl {

CallbackListReceivers::CallbackListReceivers() = default;

CallbackListReceivers::~CallbackListReceivers() {
  RTC_CHECK(!send_in_progress_);
}

void CallbackListReceivers::RemoveReceivers(const void* removal_tag) {
  RTC_DCHECK(removal_tag);

  // We divide the receivers_ vector into three regions: from right to left, the
  // "keep" region, the "todo" region, and the "remove" region. The "todo"
  // region initially covers the whole vector.
  size_t first_todo = 0;                    // First element of the "todo"
                                            // region.
  size_t first_remove = receivers_.size();  // First element of the "remove"
                                            // region.

  // Loop until the "todo" region is empty.
  while (first_todo != first_remove) {
    if (receivers_[first_todo].removal_tag != removal_tag) {
      // The first element of the "todo" region should be kept. Move the
      // "keep"/"todo" boundary.
      ++first_todo;
    } else if (receivers_[first_remove - 1].removal_tag == removal_tag) {
      // The last element of the "todo" region should be removed. Move the
      // "todo"/"remove" boundary.
      if (send_in_progress_) {
        // Tag this receiver for removal, which will be done when `ForEach`
        // has completed.
        receivers_[first_remove - 1].removal_tag = pending_removal_tag();
      }
      --first_remove;
    } else if (!send_in_progress_) {
      // The first element of the "todo" region should be removed, and the last
      // element of the "todo" region should be kept. Swap them, and then shrink
      // the "todo" region from both ends.
      RTC_DCHECK_NE(first_todo, first_remove - 1);
      using std::swap;
      swap(receivers_[first_todo], receivers_[first_remove - 1]);
      RTC_DCHECK_NE(receivers_[first_todo].removal_tag, removal_tag);
      ++first_todo;
      RTC_DCHECK_EQ(receivers_[first_remove - 1].removal_tag, removal_tag);
      --first_remove;
    }
  }

  if (!send_in_progress_) {
    // Discard the remove region.
    receivers_.resize(first_remove);
  }
}

void CallbackListReceivers::Foreach(FunctionView<void(UntypedFunction&)> fv) {
  RTC_CHECK(!send_in_progress_);
  bool removals_detected = false;
  send_in_progress_ = true;
  for (auto& r : receivers_) {
    RTC_DCHECK_NE(r.removal_tag, pending_removal_tag());
    fv(r.function);
    if (r.removal_tag == pending_removal_tag()) {
      removals_detected = true;
    }
  }
  send_in_progress_ = false;
  if (removals_detected) {
    RemoveReceivers(pending_removal_tag());
  }
}

template void CallbackListReceivers::AddReceiver(
    const void*,
    UntypedFunction::TrivialUntypedFunctionArgs<1>);
template void CallbackListReceivers::AddReceiver(
    const void*,
    UntypedFunction::TrivialUntypedFunctionArgs<2>);
template void CallbackListReceivers::AddReceiver(
    const void*,
    UntypedFunction::TrivialUntypedFunctionArgs<3>);
template void CallbackListReceivers::AddReceiver(
    const void*,
    UntypedFunction::TrivialUntypedFunctionArgs<4>);
template void CallbackListReceivers::AddReceiver(
    const void*,
    UntypedFunction::NontrivialUntypedFunctionArgs);
template void CallbackListReceivers::AddReceiver(
    const void*,
    UntypedFunction::FunctionPointerUntypedFunctionArgs);

template void CallbackListReceivers::AddReceiver(
    UntypedFunction::TrivialUntypedFunctionArgs<1>);
template void CallbackListReceivers::AddReceiver(
    UntypedFunction::TrivialUntypedFunctionArgs<2>);
template void CallbackListReceivers::AddReceiver(
    UntypedFunction::TrivialUntypedFunctionArgs<3>);
template void CallbackListReceivers::AddReceiver(
    UntypedFunction::TrivialUntypedFunctionArgs<4>);
template void CallbackListReceivers::AddReceiver(
    UntypedFunction::NontrivialUntypedFunctionArgs);
template void CallbackListReceivers::AddReceiver(
    UntypedFunction::FunctionPointerUntypedFunctionArgs);

}  // namespace callback_list_impl
}  // namespace webrtc
