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

#include "callback_watch.h"
#include "sync_manager.h"

namespace netemul {

class CounterBarrierWatch : public CallbackWatch<CounterBarrier::Callback> {
 public:
  CounterBarrierWatch(CounterBarrier* parent, uint32_t count, CounterBarrier::Callback callback)
      : CallbackWatch(std::move(callback)), count_(count), parent_(parent) {}

  void OnTimeout() override {
    FireCallback(false);
    parent_->CleanWatches();
  }

  uint32_t count() const { return count_; }

 private:
  uint32_t count_;
  // pointer to parent barrier, not owned
  CounterBarrier* parent_;
};

void CounterBarrier::AddWatch(uint32_t trigger_count, int64_t timeout, Callback callback) {
  auto watch = std::make_unique<CounterBarrierWatch>(this, trigger_count, std::move(callback));
  if (timeout > 0) {
    watch->PostTimeout(dispatcher_, timeout);
  }
  watches_.push_back(std::move(watch));
  auto watch_count = count();

  for (auto i = watches_.begin(); i != watches_.end();) {
    if (watch_count >= (*i)->count()) {
      (*i)->FireCallback(true);
      i = watches_.erase(i);
    } else {
      ++i;
    }
  }
}

void CounterBarrier::CleanWatches() {
  for (auto i = watches_.begin(); i != watches_.end();) {
    if ((*i)->valid()) {
      ++i;
    } else {
      i = watches_.erase(i);
    }
  }
}

bool CounterBarrier::empty() const { return watches_.empty(); }
size_t CounterBarrier::count() const { return watches_.size(); }

CounterBarrier::CounterBarrier(async_dispatcher_t* dispatcher) : dispatcher_(dispatcher) {}

CounterBarrier::~CounterBarrier() = default;

}  // namespace netemul
