//===-- deluxe/executionpolicies/AwaitBase.cpp ------------------*- C++ -*-===//
//
//                                 The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file deluxe/executionpolicies/AwaitBase.cpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2019
///
/// \brief Implementation for deluxe/executionpolicies/AwaitBase.h.
///
//===----------------------------------------------------------------------===//

#include "AwaitBase.h"
#include "rosa/support/debug.hpp"

#include <algorithm>
#include <sstream>

namespace rosa {
namespace deluxe {

AwaitBase::AwaitBase(const std::set<size_t> &S, CheckerType &&Checker)
    : Set(S), Checker(Checker) {}

bool AwaitBase::canHandle(const AgentHandle H, const DeluxeSystem &S) const
    noexcept {
  return isDeluxeAgent(H, S) &&
         canHandleNumberOfInputs(numberOfDeluxeAgentInputs(H, S));
}

bool AwaitBase::shouldProcess(const std::vector<bool> &InputChanged) noexcept {
  // Sanity check of usage.
  ASSERT(canHandleNumberOfInputs(InputChanged.size()));
  return Checker(Set.begin(), Set.end(),
                 [&InputChanged](const size_t I) { return InputChanged[I]; });
}

bool AwaitBase::canHandleNumberOfInputs(const size_t NumberOfInputs) const
    noexcept {
  const auto MaxElemIt = std::max_element(Set.begin(), Set.end());
  const size_t MaxElem = (MaxElemIt == Set.end()) ? 0 : *MaxElemIt;
  return MaxElem <= NumberOfInputs;
}

std::string AwaitBase::dumpS(void) const noexcept {
  std::stringstream SS;
  SS << "[";
  for (const auto &Value : Set) {
    SS << " " << Value;
  }
  SS << " ]";
  return SS.str();
}

} // End namespace deluxe
} // End namespace rosa
