// 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
