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

#include <sstream>

#include "cmExecutionStatus.h"
#include "cmListFileCache.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSystemTools.h"
#include "cmVariableWatch.h"
#include "cmake.h"

struct cmVariableWatchCallbackData
{
  bool InCallback;
  std::string Command;
};

static void cmVariableWatchCommandVariableAccessed(const std::string& variable,
                                                   int access_type,
                                                   void* client_data,
                                                   const char* newValue,
                                                   const cmMakefile* mf)
{
  cmVariableWatchCallbackData* data =
    static_cast<cmVariableWatchCallbackData*>(client_data);

  if (data->InCallback) {
    return;
  }
  data->InCallback = true;

  cmListFileFunction newLFF;
  cmListFileArgument arg;
  bool processed = false;
  const char* accessString = cmVariableWatch::GetAccessAsString(access_type);
  const char* currentListFile = mf->GetDefinition("CMAKE_CURRENT_LIST_FILE");

  /// Ultra bad!!
  cmMakefile* makefile = const_cast<cmMakefile*>(mf);

  std::string stack = makefile->GetProperty("LISTFILE_STACK");
  if (!data->Command.empty()) {
    newLFF.Arguments.clear();
    newLFF.Arguments.emplace_back(variable, cmListFileArgument::Quoted, 9999);
    newLFF.Arguments.emplace_back(accessString, cmListFileArgument::Quoted,
                                  9999);
    newLFF.Arguments.emplace_back(newValue ? newValue : "",
                                  cmListFileArgument::Quoted, 9999);
    newLFF.Arguments.emplace_back(currentListFile, cmListFileArgument::Quoted,
                                  9999);
    newLFF.Arguments.emplace_back(stack, cmListFileArgument::Quoted, 9999);
    newLFF.Name = data->Command;
    newLFF.Line = 9999;
    cmExecutionStatus status;
    if (!makefile->ExecuteCommand(newLFF, status)) {
      std::ostringstream error;
      error << "Error in cmake code at\nUnknown:0:\n"
            << "A command failed during the invocation of callback \""
            << data->Command << "\".";
      cmSystemTools::Error(error.str());
      data->InCallback = false;
      return;
    }
    processed = true;
  }
  if (!processed) {
    std::ostringstream msg;
    msg << "Variable \"" << variable << "\" was accessed using "
        << accessString << " with value \"" << (newValue ? newValue : "")
        << "\".";
    makefile->IssueMessage(MessageType::LOG, msg.str());
  }

  data->InCallback = false;
}

static void deleteVariableWatchCallbackData(void* client_data)
{
  cmVariableWatchCallbackData* data =
    static_cast<cmVariableWatchCallbackData*>(client_data);
  delete data;
}

cmVariableWatchCommand::cmVariableWatchCommand() = default;

cmVariableWatchCommand::~cmVariableWatchCommand()
{
  for (std::string const& wv : this->WatchedVariables) {
    this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch(
      wv, cmVariableWatchCommandVariableAccessed);
  }
}

bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args,
                                         cmExecutionStatus&)
{
  if (args.empty()) {
    this->SetError("must be called with at least one argument.");
    return false;
  }
  std::string const& variable = args[0];
  std::string command;
  if (args.size() > 1) {
    command = args[1];
  }
  if (variable == "CMAKE_CURRENT_LIST_FILE") {
    std::ostringstream ostr;
    ostr << "cannot be set on the variable: " << variable;
    this->SetError(ostr.str());
    return false;
  }

  cmVariableWatchCallbackData* data = new cmVariableWatchCallbackData;

  data->InCallback = false;
  data->Command = command;

  this->WatchedVariables.insert(variable);
  if (!this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch(
        variable, cmVariableWatchCommandVariableAccessed, data,
        deleteVariableWatchCallbackData)) {
    deleteVariableWatchCallbackData(data);
    return false;
  }

  return true;
}
