// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "peridot/lib/util/wait_until_idle.h"

namespace util {

IdleWaiter::Activity::Activity(fxl::WeakPtr<IdleWaiter> tracker)
    : tracker_(tracker) {
  tracker_->activity_ = this;
}

IdleWaiter::Activity::~Activity() {
  if (tracker_) {
    tracker_->activity_ = nullptr;
    tracker_->PostIdleCheck();
  }
}

IdleWaiter::IdleWaiter()
    : message_loop_(fsl::MessageLoop::GetCurrent()), weak_ptr_factory_(this) {}

IdleWaiter::~IdleWaiter() = default;

IdleWaiter::ActivityToken IdleWaiter::RegisterOngoingActivity() {
  FXL_DCHECK(message_loop_ == fsl::MessageLoop::GetCurrent());

  if (activity_) {
    return ActivityToken(activity_);
  } else {
    // |activity_| is set in the |Activity| constructor and cleared in
    // the destructor
    return fxl::MakeRefCounted<Activity>(weak_ptr_factory_.GetWeakPtr());
  }
}

void IdleWaiter::WaitUntilIdle(fxl::Closure callback) {
  callbacks_.push_back(std::move(callback));
  PostIdleCheck();
}

void IdleWaiter::PostIdleCheck() {
  if (!(callbacks_.empty() || activity_ || idle_check_pending_)) {
    FXL_DCHECK(message_loop_ == fsl::MessageLoop::GetCurrent());
    message_loop_->PostQuitTask();
    idle_check_pending_ = true;
  }
}

bool IdleWaiter::FinishIdleCheck() {
  if (idle_check_pending_) {
    message_loop_->RunUntilIdle();
    if (!activity_) {
      for (const auto& callback : callbacks_) {
        callback();
      }
      callbacks_.clear();
    }
    // Otherwise, |PostIdleCheck| will be invoked again when |activity_| is
    // released.

    idle_check_pending_ = false;
    return true;
  } else {
    return false;
  }
}

}  // namespace util
