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

#include <cmsys/auto_ptr.hxx>

bool cmForEachFunctionBlocker::
IsFunctionBlocked(const cmListFileFunction& lff, cmMakefile &mf,
                  cmExecutionStatus &inStatus)
{
  if (!cmSystemTools::Strucmp(lff.Name.c_str(),"foreach"))
    {
    // record the number of nested foreach commands
    this->Depth++;
    }
  else if (!cmSystemTools::Strucmp(lff.Name.c_str(),"endforeach"))
    {
    // if this is the endofreach for this statement
    if (!this->Depth) 
      {
      // Remove the function blocker for this scope or bail.
      cmsys::auto_ptr<cmFunctionBlocker>
        fb(mf.RemoveFunctionBlocker(this, lff));
      if(!fb.get()) { return false; }

      // at end of for each execute recorded commands
      // store the old value
      std::string oldDef;
      if (mf.GetDefinition(this->Args[0].c_str()))
        {
        oldDef = mf.GetDefinition(this->Args[0].c_str());
        }
      std::vector<std::string>::const_iterator j = this->Args.begin();
      ++j;

      std::string tmps;
      cmListFileArgument arg;
      for( ; j != this->Args.end(); ++j)
        {   
        // set the variable to the loop value
        mf.AddDefinition(this->Args[0].c_str(),j->c_str());
        // Invoke all the functions that were collected in the block.
        cmExecutionStatus status;
        for(unsigned int c = 0; c < this->Functions.size(); ++c)
          {
          status.Clear();
          mf.ExecuteCommand(this->Functions[c],status);
          if (status.GetReturnInvoked())
            {
            inStatus.SetReturnInvoked(true);
            // restore the variable to its prior value
            mf.AddDefinition(this->Args[0].c_str(),oldDef.c_str());
            return true;
            }
          if (status.GetBreakInvoked())
            {
            // restore the variable to its prior value
            mf.AddDefinition(this->Args[0].c_str(),oldDef.c_str());
            return true;
            }
          if(cmSystemTools::GetFatalErrorOccured() )
            {
            return true;
            }
          }
        }
      // restore the variable to its prior value
      mf.AddDefinition(this->Args[0].c_str(),oldDef.c_str());
      return true;
      }
    else
      {
      // close out a nested foreach
      this->Depth--;
      }
    }
  
  // record the command
  this->Functions.push_back(lff);
  
  // always return true
  return true;
}

bool cmForEachFunctionBlocker::
ShouldRemove(const cmListFileFunction& lff, cmMakefile& mf)
{
  if(!cmSystemTools::Strucmp(lff.Name.c_str(),"endforeach"))
    {
    std::vector<std::string> expandedArguments;
    mf.ExpandArguments(lff.Arguments, expandedArguments);
    // if the endforeach has arguments then make sure
    // they match the begin foreach arguments
    if ((expandedArguments.empty() ||
         (expandedArguments[0] == this->Args[0])))
      {
      return true;
      }
    }
  return false;
}

bool cmForEachCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(args.size() < 1)
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }
  if(args.size() > 1 && args[1] == "IN")
    {
    return this->HandleInMode(args);
    }
  
  // create a function blocker
  cmForEachFunctionBlocker *f = new cmForEachFunctionBlocker();
  if ( args.size() > 1 )
    {
    if ( args[1] == "RANGE" )
      {
      int start = 0;
      int stop = 0;
      int step = 0;
      if ( args.size() == 3 )
        {
        stop = atoi(args[2].c_str());
        }
      if ( args.size() == 4 )
        {
        start = atoi(args[2].c_str());
        stop = atoi(args[3].c_str());
        }
      if ( args.size() == 5 )
        {
        start = atoi(args[2].c_str());
        stop = atoi(args[3].c_str());
        step = atoi(args[4].c_str());
        }
      if ( step == 0 )
        {
        if ( start > stop )
          {
          step = -1;
          }
        else
          {
          step = 1;
          }
        }
      if ( 
        (start > stop && step > 0) ||
        (start < stop && step < 0) ||
        step == 0
        )
        {
        cmOStringStream str;
        str << "called with incorrect range specification: start ";
        str << start << ", stop " << stop << ", step " << step;
        this->SetError(str.str().c_str());
        return false;
        }
      std::vector<std::string> range;
      char buffer[100];
      range.push_back(args[0]);
      int cc;
      for ( cc = start; ; cc += step )
        {
        if ( (step > 0 && cc > stop) || (step < 0 && cc < stop) )
          {
          break;
          }
        sprintf(buffer, "%d", cc);
        range.push_back(buffer);
        if ( cc == stop )
          {
          break;
          }
        }
      f->Args = range;
      }
    else
      {
      f->Args = args;
      }
    }
  else
    {
    f->Args = args;
    }
  this->Makefile->AddFunctionBlocker(f);
  
  return true;
}

//----------------------------------------------------------------------------
bool cmForEachCommand::HandleInMode(std::vector<std::string> const& args)
{
  cmsys::auto_ptr<cmForEachFunctionBlocker> f(new cmForEachFunctionBlocker());
  f->Args.push_back(args[0]);

  enum Doing { DoingNone, DoingLists, DoingItems };
  Doing doing = DoingNone;
  for(unsigned int i=2; i < args.size(); ++i)
    {
    if(doing == DoingItems)
      {
      f->Args.push_back(args[i]);
      }
    else if(args[i] == "LISTS")
      {
      doing = DoingLists;
      }
    else if(args[i] == "ITEMS")
      {
      doing = DoingItems;
      }
    else if(doing == DoingLists)
      {
      const char* value = this->Makefile->GetDefinition(args[i].c_str());
      if(value && *value)
        {
        cmSystemTools::ExpandListArgument(value, f->Args, true);
        }
      }
    else
      {
      cmOStringStream e;
      e << "Unknown argument:\n" << "  " << args[i] << "\n";
      this->Makefile->IssueMessage(cmake::FATAL_ERROR, e.str());
      return true;
      }
    }

  this->Makefile->AddFunctionBlocker(f.release()); // TODO: pass auto_ptr
  return true;
}
