/*============================================================================
  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"

//----------------------------------------------------------------------------
static void cmVariableWatchCommandVariableAccessed(
  const std::string& variable, int access_type, void* client_data,
  const char* newValue, const cmMakefile* mf)
{
  cmVariableWatchCommand* command
    = static_cast<cmVariableWatchCommand*>(client_data);
  command->VariableAccessed(variable, access_type, newValue, mf);
}

//----------------------------------------------------------------------------
cmVariableWatchCommand::cmVariableWatchCommand()
{
  this->InCallback = false;
}

//----------------------------------------------------------------------------
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];
  if ( args.size() > 1 )
    {
    std::string command = args[1];
    this->Handlers[variable].Commands.push_back(args[1]);
    }
  if ( variable == "CMAKE_CURRENT_LIST_FILE" )
    {
    cmOStringStream ostr;
    ostr << "cannot be set on the variable: " << variable.c_str();
    this->SetError(ostr.str().c_str());
    return false;
    }

  this->Makefile->GetCMakeInstance()->GetVariableWatch()->AddWatch(
    variable, cmVariableWatchCommandVariableAccessed, this);

  return true;
}

//----------------------------------------------------------------------------
void cmVariableWatchCommand::VariableAccessed(const std::string& variable,
  int access_type, const char* newValue, const cmMakefile* mf)
{
  if ( this->InCallback )
    {
    return;
    }
  this->InCallback = true;

  cmListFileFunction newLFF;
  cmVariableWatchCommandHandler *handler = &this->Handlers[variable];
  cmVariableWatchCommandHandler::VectorOfCommands::iterator it;
  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");
  for ( it = handler->Commands.begin(); it != handler->Commands.end();
    ++ it )
    {
    std::string command = *it;
    newLFF.Arguments.clear();
    newLFF.Arguments.push_back(
      cmListFileArgument(variable, true, "unknown", 9999));
    newLFF.Arguments.push_back(
      cmListFileArgument(accessString, true, "unknown", 9999));
    newLFF.Arguments.push_back(
      cmListFileArgument(newValue?newValue:"", true, "unknown", 9999));
    newLFF.Arguments.push_back(
      cmListFileArgument(currentListFile, true, "unknown", 9999));
    newLFF.Arguments.push_back(
      cmListFileArgument(stack, true, "unknown", 9999));
    newLFF.Name = command;
    newLFF.FilePath = "Some weird path";
    newLFF.Line = 9999;
    cmExecutionStatus status;
    if(!makefile->ExecuteCommand(newLFF,status))
      {
      arg.FilePath =  "Unknown";
      arg.Line = 0;
      cmOStringStream error;
      error << "Error in cmake code at\n"
        << arg.FilePath << ":" << arg.Line << ":\n"
        << "A command failed during the invocation of callback\""
        << command << "\".";
      cmSystemTools::Error(error.str().c_str());
      this->InCallback = false;
      return;
      }
    processed = true;
    }
  if ( !processed )
    {
    cmOStringStream msg;
    msg << "* Variable \"" << variable.c_str() << "\" was accessed using "
      << accessString << " in: " << currentListFile << std::endl;
    msg << "  The value of the variable: \"" << newValue << "\"" << std::endl;
    msg << "  The list file stack: " << stack.c_str();
    cmSystemTools::Message(msg.str().c_str());
    std::vector<std::string> vars = makefile->GetDefinitions();
    cmOStringStream msg2;
    size_t cc;
    for ( cc = 0; cc < vars.size(); cc ++ )
      {
      if ( vars[cc] == variable )
        {
        continue;
        }
      msg2 << vars[cc] << " = \""
        << makefile->GetDefinition(vars[cc].c_str()) << "\"" << std::endl;
      }
    //cmSystemTools::Message(msg2.str().c_str());
    }
  this->InCallback = false;
}
