/*
 *  Copyright 2019 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/operations_chain.h"

#include "rtc_base/checks.h"

namespace rtc {

OperationsChain::CallbackHandle::CallbackHandle(
    scoped_refptr<OperationsChain> operations_chain)
    : operations_chain_(std::move(operations_chain)) {}

OperationsChain::CallbackHandle::~CallbackHandle() {
  RTC_DCHECK(has_run_);
}

void OperationsChain::CallbackHandle::OnOperationComplete() {
  RTC_DCHECK(!has_run_);
#ifdef RTC_DCHECK_IS_ON
  has_run_ = true;
#endif  // RTC_DCHECK_IS_ON
  operations_chain_->OnOperationComplete();
  // We have no reason to keep the |operations_chain_| alive through reference
  // counting anymore.
  operations_chain_ = nullptr;
}

// static
scoped_refptr<OperationsChain> OperationsChain::Create() {
  return new OperationsChain();
}

OperationsChain::OperationsChain() : RefCountedObject() {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
}

OperationsChain::~OperationsChain() {
  // Operations keep the chain alive through reference counting so this should
  // not be possible. The fact that the chain is empty makes it safe to
  // destroy the OperationsChain on any sequence.
  RTC_DCHECK(chained_operations_.empty());
}

void OperationsChain::SetOnChainEmptyCallback(
    std::function<void()> on_chain_empty_callback) {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  on_chain_empty_callback_ = std::move(on_chain_empty_callback);
}

bool OperationsChain::IsEmpty() const {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  return chained_operations_.empty();
}

std::function<void()> OperationsChain::CreateOperationsChainCallback() {
  return [handle = rtc::scoped_refptr<CallbackHandle>(
              new CallbackHandle(this))]() { handle->OnOperationComplete(); };
}

void OperationsChain::OnOperationComplete() {
  RTC_DCHECK_RUN_ON(&sequence_checker_);
  // The front element is the operation that just completed, remove it.
  RTC_DCHECK(!chained_operations_.empty());
  chained_operations_.pop();
  // If there are any other operations chained, execute the next one. Otherwise,
  // invoke the "on chain empty" callback if it has been set.
  if (!chained_operations_.empty()) {
    chained_operations_.front()->Run();
  } else if (on_chain_empty_callback_.has_value()) {
    on_chain_empty_callback_.value()();
  }
}

}  // namespace rtc
