/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2000-2009 Kitware, Inc., Insight Software Consortium

  Distributed under the OSI-approved BSD License (the "License");
  see accompanying file Copyright.txt for details.

  This software is distributed WITHOUT ANY WARRANTY; without even the
  implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  See the License for more information.
============================================================================*/
#include "cmVariableWatchCommand.h"

#include "cmVariableWatch.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.push_back(
      cmListFileArgument(variable, cmListFileArgument::Quoted, 9999));
    newLFF.Arguments.push_back(
      cmListFileArgument(accessString, cmListFileArgument::Quoted, 9999));
    newLFF.Arguments.push_back(cmListFileArgument(
      newValue ? newValue : "", cmListFileArgument::Quoted, 9999));
    newLFF.Arguments.push_back(
      cmListFileArgument(currentListFile, cmListFileArgument::Quoted, 9999));
    newLFF.Arguments.push_back(
      cmListFileArgument(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().c_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(cmake::LOG, msg.str());
  }

  data->InCallback = false;
}

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

cmVariableWatchCommand::cmVariableWatchCommand()
{
}

cmVariableWatchCommand::~cmVariableWatchCommand()
{
  std::set<std::string>::const_iterator it;
  for (it = this->WatchedVariables.begin(); it != this->WatchedVariables.end();
       ++it) {
    this->Makefile->GetCMakeInstance()->GetVariableWatch()->RemoveWatch(
      *it, cmVariableWatchCommandVariableAccessed);
  }
}

bool cmVariableWatchCommand::InitialPass(std::vector<std::string> const& args,
                                         cmExecutionStatus&)
{
  if (args.size() < 1) {
    this->SetError("must be called with at least one argument.");
    return false;
  }
  std::string 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;
}
