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

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

static const char* const cmVariableWatchAccessStrings[] = {
  "READ_ACCESS",     "UNKNOWN_READ_ACCESS", "UNKNOWN_DEFINED_ACCESS",
  "MODIFIED_ACCESS", "REMOVED_ACCESS",      "NO_ACCESS"
};

const char* cmVariableWatch::GetAccessAsString(int access_type)
{
  if (access_type < 0 || access_type >= cmVariableWatch::NO_ACCESS) {
    return "NO_ACCESS";
  }
  return cmVariableWatchAccessStrings[access_type];
}

cmVariableWatch::cmVariableWatch() = default;

cmVariableWatch::~cmVariableWatch() = default;

bool cmVariableWatch::AddWatch(const std::string& 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(const std::string& 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(const std::string& variable,
                                       int access_type, const char* newValue,
                                       const cmMakefile* mf) const
{
  cmVariableWatch::StringToVectorOfPairs::const_iterator 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, access_type, it->ClientData, newValue, mf);
      }
    }
    return true;
  }
  return false;
}
