/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file LICENSE.rst or https://cmake.org/licensing for details.  */
#include "cmVariableWatch.h"

#include <array>
#include <memory>
#include <utility>
#include <vector>

std::string const& cmVariableWatch::GetAccessAsString(AccessType accessType)
{
  static std::array<std::string, 6> const cmVariableWatchAccessStrings = {
    { "READ_ACCESS", "UNKNOWN_READ_ACCESS", "UNKNOWN_DEFINED_ACCESS",
      "MODIFIED_ACCESS", "REMOVED_ACCESS", "NO_ACCESS" }
  };
  if (accessType >= cmVariableWatch::NO_ACCESS) {
    accessType = cmVariableWatch::NO_ACCESS;
  }
  return cmVariableWatchAccessStrings[accessType];
}

cmVariableWatch::cmVariableWatch() = default;

cmVariableWatch::~cmVariableWatch() = default;

bool cmVariableWatch::AddWatch(std::string const& variable, WatchMethod method,
                               void* client_data /*=0*/,
                               DeleteData delete_data /*=0*/)
{
  auto p = std::make_shared<cmVariableWatch::Pair>();
  p->Method = method;
  p->ClientData = client_data;
  p->DeleteDataCall = delete_data;
  cmVariableWatch::VectorOfPairs& vp = this->WatchMap[variable];
  for (auto& pair : vp) {
    if (pair->Method == method && client_data &&
        client_data == pair->ClientData) {
      // Callback already exists
      return false;
    }
  }
  vp.push_back(std::move(p));
  return true;
}

void cmVariableWatch::RemoveWatch(std::string const& variable,
                                  WatchMethod method, void* client_data /*=0*/)
{
  if (!this->WatchMap.count(variable)) {
    return;
  }
  cmVariableWatch::VectorOfPairs* vp = &this->WatchMap[variable];
  cmVariableWatch::VectorOfPairs::iterator it;
  for (it = vp->begin(); it != vp->end(); ++it) {
    if ((*it)->Method == method &&
        // If client_data is NULL, we want to disconnect all watches against
        // the given method; otherwise match ClientData as well.
        (!client_data || (client_data == (*it)->ClientData))) {
      vp->erase(it);
      return;
    }
  }
}

bool cmVariableWatch::VariableAccessed(std::string const& variable,
                                       AccessType accessType,
                                       char const* newValue,
                                       cmMakefile const* mf) const
{
  auto mit = this->WatchMap.find(variable);
  if (mit != this->WatchMap.end()) {
    // The strategy here is to copy the list of callbacks, and ignore
    // new callbacks that existing ones may add.
    std::vector<std::weak_ptr<Pair>> vp(mit->second.begin(),
                                        mit->second.end());
    for (auto& weak_it : vp) {
      // In the case where a callback was removed, the weak_ptr will not be
      // lockable, and so this ensures we don't attempt to call into freed
      // memory
      if (auto it = weak_it.lock()) {
        it->Method(variable, accessType, it->ClientData, newValue, mf);
      }
    }
    return true;
  }
  return false;
}
