// 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/idle_waiter.h"

#include <lib/async/cpp/task.h>
#include <lib/async/default.h>

namespace util {

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

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

IdleWaiter::IdleWaiter() : weak_ptr_factory_(this) {}

IdleWaiter::~IdleWaiter() = default;

void IdleWaiter::SetLoop(async::Loop* loop) {
  FXL_DCHECK(!loop_);
  loop_ = loop;
}

IdleWaiter::ActivityToken IdleWaiter::RegisterOngoingActivity() {
  // !loop_ for unit tests
  FXL_DCHECK(!loop_ || loop_->dispatcher() == async_get_default_dispatcher());

  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(fit::closure callback) {
  callbacks_.push_back(std::move(callback));
  PostIdleCheck();
}

void IdleWaiter::PostIdleCheck() {
  FXL_DCHECK(loop_) << "No message loop set for debug features. If this is a "
                       "unit test rather than an integration test, consider "
                       "using //garnet/public/lib/gtest gtest::TestLoopFixture "
                       "features instead.";

  if (!(callbacks_.empty() || activity_ || idle_check_pending_)) {
    FXL_DCHECK(loop_->dispatcher() == async_get_default_dispatcher());
    loop_->Quit();
    idle_check_pending_ = true;
  }
}

bool IdleWaiter::FinishIdleCheck() {
  if (idle_check_pending_) {
    FXL_DCHECK(loop_ && loop_->dispatcher() == async_get_default_dispatcher());
    loop_->RunUntilIdle();
    loop_->ResetQuit();
    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
