/*============================================================================
  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]))
        {
        oldDef = mf.GetDefinition(this->Args[0]);
        }
      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],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],oldDef.c_str());
            return true;
            }
          if (status.GetBreakInvoked())
            {
            // restore the variable to its prior value
            mf.AddDefinition(this->Args[0],oldDef.c_str());
            return true;
            }
          if(cmSystemTools::GetFatalErrorOccured() )
            {
            return true;
            }
          }
        }
      // restore the variable to its prior value
      mf.AddDefinition(this->Args[0],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());
        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]);
      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;
}
