// 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 "src/ledger/bin/testing/loop_controller_test_loop.h"

#include <lib/async/cpp/task.h>
#include <lib/fit/defer.h>

#include <memory>

namespace ledger {

namespace {

class SubLoopTestLoop : public SubLoop {
 public:
  explicit SubLoopTestLoop(LoopController* controller,
                           std::unique_ptr<async::LoopInterface> loop_interface)
      : controller_(controller), loop_interface_(std::move(loop_interface)) {}

  void DrainAndQuit() override {
    // TODO(qsr): Implement drain on TestLoop.
    auto waiter = controller_->NewWaiter();
    async::PostTask(dispatcher(), waiter->GetCallback());
    FXL_CHECK(waiter->RunUntilCalled());
  }

  async_dispatcher_t* dispatcher() override { return loop_interface_->dispatcher(); }

 private:
  LoopController* controller_;
  std::unique_ptr<async::LoopInterface> loop_interface_;
};

class CallbackWaiterImpl : public CallbackWaiter {
 public:
  explicit CallbackWaiterImpl(LoopController* loop) : loop_(loop) {}
  CallbackWaiterImpl(const CallbackWaiterImpl&) = delete;
  CallbackWaiterImpl& operator=(const CallbackWaiterImpl&) = delete;
  ~CallbackWaiterImpl() override = default;

  fit::function<void()> GetCallback() override {
    return [this] {
      ++callback_called_count_;
      if (running_) {
        loop_->StopLoop();
      }
    };
  }

  bool RunUntilCalled() override {
    FXL_DCHECK(!running_);
    running_ = true;
    auto cleanup = fit::defer([this] { running_ = false; });
    bool called = loop_->RunLoopUntil([this] { return !NotCalledYet(); });
    if (called) {
      ++run_until_called_count_;
    }
    return called;
  }

  bool NotCalledYet() override { return callback_called_count_ <= run_until_called_count_; }

 private:
  LoopController* loop_;
  size_t callback_called_count_ = 0;
  size_t run_until_called_count_ = 0;
  // Whether the waiter is currently in the |RunUntilCalled| method.
  bool running_ = false;
};

}  // namespace

LoopControllerTestLoop::LoopControllerTestLoop(async::TestLoop* loop) : loop_(loop) {}

LoopControllerTestLoop::~LoopControllerTestLoop() {}

void LoopControllerTestLoop::RunLoop() { loop_->RunUntilIdle(); }

void LoopControllerTestLoop::StopLoop() { loop_->Quit(); }

std::unique_ptr<SubLoop> LoopControllerTestLoop::StartNewLoop() {
  return std::make_unique<SubLoopTestLoop>(
      this, std::unique_ptr<async::LoopInterface>(loop_->StartNewLoop().release()));
}

std::unique_ptr<CallbackWaiter> LoopControllerTestLoop::NewWaiter() {
  return std::make_unique<CallbackWaiterImpl>(this);
}

async_dispatcher_t* LoopControllerTestLoop::dispatcher() { return loop_->dispatcher(); }

bool LoopControllerTestLoop::RunLoopUntil(fit::function<bool()> condition) {
  if (condition()) {
    return true;
  }
  // The condition is not true, but might be triggered after some delay due to a
  // delayed task (for example, because of backoffs). Try to advance the loop in
  // bigger and bigger increment. Fail if the event does not occur after ~100s
  // as if something doesn't happen in 100 simulated s, then it will almost
  // certainly be a problem for tests using a real loop.
  for (size_t i : {0, 1, 10, 100}) {
    loop_->RunFor(zx::sec(i));
    if (condition()) {
      return true;
    }
  }
  return false;
}

void LoopControllerTestLoop::RunLoopFor(zx::duration duration) { loop_->RunFor(duration); }

}  // namespace ledger
