/*============================================================================
  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 "cmListCommand.h"
#include <cmsys/RegularExpression.hxx>
#include <cmsys/SystemTools.hxx>

#include <stdlib.h> // required for atoi
#include <ctype.h>
#include <assert.h>
//----------------------------------------------------------------------------
bool cmListCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(args.size() < 2)
    {
    this->SetError("must be called with at least two arguments.");
    return false;
    }

  const std::string &subCommand = args[0];
  if(subCommand == "LENGTH")
    {
    return this->HandleLengthCommand(args);
    }
  if(subCommand == "GET")
    {
    return this->HandleGetCommand(args);
    }
  if(subCommand == "APPEND")
    {
    return this->HandleAppendCommand(args);
    }
  if(subCommand == "FIND")
    {
    return this->HandleFindCommand(args);
    }
  if(subCommand == "INSERT")
    {
    return this->HandleInsertCommand(args);
    }
  if(subCommand == "REMOVE_AT")
    {
    return this->HandleRemoveAtCommand(args);
    }
  if(subCommand == "REMOVE_ITEM")
    {
    return this->HandleRemoveItemCommand(args);
    }
  if(subCommand == "REMOVE_DUPLICATES")
    {
    return this->HandleRemoveDuplicatesCommand(args);
    }
  if(subCommand == "SORT")
    {
    return this->HandleSortCommand(args);
    }
  if(subCommand == "REVERSE")
    {
    return this->HandleReverseCommand(args);
    }

  std::string e = "does not recognize sub-command "+subCommand;
  this->SetError(e.c_str());
  return false;
}

//----------------------------------------------------------------------------
bool cmListCommand::GetListString(std::string& listString, const char* var)
{
  if ( !var )
    {
    return false;
    }
  // get the old value
  const char* cacheValue
    = this->Makefile->GetDefinition(var);
  if(!cacheValue)
    {
    return false;
    }
  listString = cacheValue;
  return true;
}

//----------------------------------------------------------------------------
bool cmListCommand::GetList(std::vector<std::string>& list, const char* var)
{
  std::string listString;
  if ( !this->GetListString(listString, var) )
    {
    return false;
    }
  // if the size of the list
  if(listString.size() == 0)
    {
    return true;
    }
  // expand the variable into a list
  cmSystemTools::ExpandListArgument(listString, list, true);
  // check the list for empty values
  bool hasEmpty = false;
  for(std::vector<std::string>::iterator i = list.begin();
      i != list.end(); ++i)
    {
    if(i->size() == 0)
      {
      hasEmpty = true;
      break;
      }
    }
  // if no empty elements then just return
  if(!hasEmpty)
    {
    return true;
    }
  // if we have empty elements we need to check policy CMP0007
  switch(this->Makefile->GetPolicyStatus(cmPolicies::CMP0007))
    {
    case cmPolicies::WARN:
      {
      // Default is to warn and use old behavior
      // OLD behavior is to allow compatibility, so recall
      // ExpandListArgument without the true which will remove
      // empty values
      list.clear();
      cmSystemTools::ExpandListArgument(listString, list);
      std::string warn = this->Makefile->GetPolicies()->
        GetPolicyWarning(cmPolicies::CMP0007);
      warn += " List has value = [";
      warn += listString;
      warn += "].";
      this->Makefile->IssueMessage(cmake::AUTHOR_WARNING,
                                   warn);
      return true;
      }
    case cmPolicies::OLD:
      // OLD behavior is to allow compatibility, so recall
      // ExpandListArgument without the true which will remove
      // empty values
      list.clear();
      cmSystemTools::ExpandListArgument(listString, list);
      return true;
    case cmPolicies::NEW:
      return true;
    case cmPolicies::REQUIRED_IF_USED:
    case cmPolicies::REQUIRED_ALWAYS:
      this->Makefile->IssueMessage(
        cmake::FATAL_ERROR,
        this->Makefile->GetPolicies()
        ->GetRequiredPolicyError(cmPolicies::CMP0007)
        );
      return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmListCommand::HandleLengthCommand(std::vector<std::string> const& args)
{
  if(args.size() != 3)
    {
    this->SetError("sub-command LENGTH requires two arguments.");
    return false;
    }

  const std::string& listName = args[1];
  const std::string& variableName = args[args.size() - 1];
  std::vector<std::string> varArgsExpanded;
  // do not check the return value here
  // if the list var is not found varArgsExpanded will have size 0
  // and we will return 0
  this->GetList(varArgsExpanded, listName.c_str());
  size_t length = varArgsExpanded.size();
  char buffer[1024];
  sprintf(buffer, "%d", static_cast<int>(length));

  this->Makefile->AddDefinition(variableName.c_str(), buffer);
  return true;
}

//----------------------------------------------------------------------------
bool cmListCommand::HandleGetCommand(std::vector<std::string> const& args)
{
  if(args.size() < 4)
    {
    this->SetError("sub-command GET requires at least three arguments.");
    return false;
    }

  const std::string& listName = args[1];
  const std::string& variableName = args[args.size() - 1];
  // expand the variable
  std::vector<std::string> varArgsExpanded;
  if ( !this->GetList(varArgsExpanded, listName.c_str()) )
    {
    this->Makefile->AddDefinition(variableName.c_str(), "NOTFOUND");
    return true;
    }
  // FIXME: Add policy to make non-existing lists an error like empty lists.
  if(varArgsExpanded.empty())
    {
    this->SetError("GET given empty list");
    return false;
    }

  std::string value;
  size_t cc;
  const char* sep = "";
  for ( cc = 2; cc < args.size()-1; cc ++ )
    {
    int item = atoi(args[cc].c_str());
    value += sep;
    sep = ";";
    size_t nitem = varArgsExpanded.size();
    if ( item < 0 )
      {
      item = (int)nitem + item;
      }
    if ( item < 0 || nitem <= (size_t)item )
      {
      cmOStringStream str;
      str << "index: " << item << " out of range (-"
          << varArgsExpanded.size() << ", "
          << varArgsExpanded.size()-1 << ")";
      this->SetError(str.str().c_str());
      return false;
      }
    value += varArgsExpanded[item];
    }

  this->Makefile->AddDefinition(variableName.c_str(), value.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmListCommand::HandleAppendCommand(std::vector<std::string> const& args)
{
  assert(args.size() >= 2);

  // Skip if nothing to append.
  if(args.size() < 3)
    {
    return true;
    }

  const std::string& listName = args[1];
  // expand the variable
  std::string listString;
  this->GetListString(listString, listName.c_str());
  size_t cc;
  for ( cc = 2; cc < args.size(); ++ cc )
    {
    if(listString.size())
      {
      listString += ";";
      }
    listString += args[cc];
    }

  this->Makefile->AddDefinition(listName.c_str(), listString.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmListCommand::HandleFindCommand(std::vector<std::string> const& args)
{
  if(args.size() != 4)
    {
    this->SetError("sub-command FIND requires three arguments.");
    return false;
    }

  const std::string& listName = args[1];
  const std::string& variableName = args[args.size() - 1];
  // expand the variable
  std::vector<std::string> varArgsExpanded;
  if ( !this->GetList(varArgsExpanded, listName.c_str()) )
    {
    this->Makefile->AddDefinition(variableName.c_str(), "-1");
    return true;
    }

  std::vector<std::string>::iterator it;
  unsigned int index = 0;
  for ( it = varArgsExpanded.begin(); it != varArgsExpanded.end(); ++ it )
    {
    if ( *it == args[2] )
      {
      char indexString[32];
      sprintf(indexString, "%d", index);
      this->Makefile->AddDefinition(variableName.c_str(), indexString);
      return true;
      }
    index++;
    }

  this->Makefile->AddDefinition(variableName.c_str(), "-1");
  return true;
}

//----------------------------------------------------------------------------
bool cmListCommand::HandleInsertCommand(std::vector<std::string> const& args)
{
  if(args.size() < 4)
    {
    this->SetError("sub-command INSERT requires at least three arguments.");
    return false;
    }

  const std::string& listName = args[1];

  // expand the variable
  int item = atoi(args[2].c_str());
  std::vector<std::string> varArgsExpanded;
  if((!this->GetList(varArgsExpanded, listName.c_str())
      || varArgsExpanded.empty()) && item != 0)
    {
    cmOStringStream str;
    str << "index: " << item << " out of range (0, 0)";
    this->SetError(str.str().c_str());
    return false;
    }

  if ( varArgsExpanded.size() != 0 )
    {
    size_t nitem = varArgsExpanded.size();
    if ( item < 0 )
      {
      item = (int)nitem + item;
      }
    if ( item < 0 || nitem <= (size_t)item )
      {
      cmOStringStream str;
      str << "index: " << item << " out of range (-"
        << varArgsExpanded.size() << ", "
        << (varArgsExpanded.size() == 0?0:(varArgsExpanded.size()-1)) << ")";
      this->SetError(str.str().c_str());
      return false;
      }
    }
  size_t cc;
  size_t cnt = 0;
  for ( cc = 3; cc < args.size(); ++ cc )
    {
    varArgsExpanded.insert(varArgsExpanded.begin()+item+cnt, args[cc]);
    cnt ++;
    }

  std::string value;
  const char* sep = "";
  for ( cc = 0; cc < varArgsExpanded.size(); cc ++ )
    {
    value += sep;
    value += varArgsExpanded[cc];
    sep = ";";
    }

  this->Makefile->AddDefinition(listName.c_str(), value.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmListCommand
::HandleRemoveItemCommand(std::vector<std::string> const& args)
{
  if(args.size() < 3)
    {
    this->SetError("sub-command REMOVE_ITEM requires two or more arguments.");
    return false;
    }

  const std::string& listName = args[1];
  // expand the variable
  std::vector<std::string> varArgsExpanded;
  if ( !this->GetList(varArgsExpanded, listName.c_str()) )
    {
    this->SetError("sub-command REMOVE_ITEM requires list to be present.");
    return false;
    }

  size_t cc;
  for ( cc = 2; cc < args.size(); ++ cc )
    {
    size_t kk = 0;
    while ( kk < varArgsExpanded.size() )
      {
      if ( varArgsExpanded[kk] == args[cc] )
        {
        varArgsExpanded.erase(varArgsExpanded.begin()+kk);
        }
      else
        {
        kk ++;
        }
      }
    }

  std::string value;
  const char* sep = "";
  for ( cc = 0; cc < varArgsExpanded.size(); cc ++ )
    {
    value += sep;
    value += varArgsExpanded[cc];
    sep = ";";
    }

  this->Makefile->AddDefinition(listName.c_str(), value.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmListCommand
::HandleReverseCommand(std::vector<std::string> const& args)
{
  assert(args.size() >= 2);
  if(args.size() > 2)
    {
    this->SetError(
      "sub-command REVERSE only takes one argument.");
    return false;
    }

  const std::string& listName = args[1];
  // expand the variable
  std::vector<std::string> varArgsExpanded;
  if ( !this->GetList(varArgsExpanded, listName.c_str()) )
    {
    this->SetError("sub-command REVERSE requires list to be present.");
    return false;
    }

  std::string value;
  std::vector<std::string>::reverse_iterator it;
  const char* sep = "";
  for ( it = varArgsExpanded.rbegin(); it != varArgsExpanded.rend(); ++ it )
    {
    value += sep;
    value += it->c_str();
    sep = ";";
    }

  this->Makefile->AddDefinition(listName.c_str(), value.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmListCommand
::HandleRemoveDuplicatesCommand(std::vector<std::string> const& args)
{
  assert(args.size() >= 2);
  if(args.size() > 2)
    {
    this->SetError(
      "sub-command REMOVE_DUPLICATES only takes one argument.");
    return false;
    }

  const std::string& listName = args[1];
  // expand the variable
  std::vector<std::string> varArgsExpanded;
  if ( !this->GetList(varArgsExpanded, listName.c_str()) )
    {
    this->SetError(
      "sub-command REMOVE_DUPLICATES requires list to be present.");
    return false;
    }

  std::string value;


  std::set<std::string> unique;
  std::vector<std::string>::iterator it;
  const char* sep = "";
  for ( it = varArgsExpanded.begin(); it != varArgsExpanded.end(); ++ it )
    {
    if (unique.find(*it) != unique.end())
      {
      continue;
      }
    unique.insert(*it);
    value += sep;
    value += it->c_str();
    sep = ";";
    }


  this->Makefile->AddDefinition(listName.c_str(), value.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmListCommand
::HandleSortCommand(std::vector<std::string> const& args)
{
  assert(args.size() >= 2);
  if(args.size() > 2)
    {
    this->SetError(
      "sub-command SORT only takes one argument.");
    return false;
    }

  const std::string& listName = args[1];
  // expand the variable
  std::vector<std::string> varArgsExpanded;
  if ( !this->GetList(varArgsExpanded, listName.c_str()) )
    {
    this->SetError("sub-command SORT requires list to be present.");
    return false;
    }

  std::sort(varArgsExpanded.begin(), varArgsExpanded.end());

  std::string value;
  std::vector<std::string>::iterator it;
  const char* sep = "";
  for ( it = varArgsExpanded.begin(); it != varArgsExpanded.end(); ++ it )
    {
    value += sep;
    value += it->c_str();
    sep = ";";
    }

  this->Makefile->AddDefinition(listName.c_str(), value.c_str());
  return true;
}

//----------------------------------------------------------------------------
bool cmListCommand::HandleRemoveAtCommand(
  std::vector<std::string> const& args)
{
  if(args.size() < 3)
    {
    this->SetError("sub-command REMOVE_AT requires at least "
                   "two arguments.");
    return false;
    }

  const std::string& listName = args[1];
  // expand the variable
  std::vector<std::string> varArgsExpanded;
  if ( !this->GetList(varArgsExpanded, listName.c_str()) )
    {
    this->SetError("sub-command REMOVE_AT requires list to be present.");
    return false;
    }
  // FIXME: Add policy to make non-existing lists an error like empty lists.
  if(varArgsExpanded.empty())
    {
    this->SetError("REMOVE_AT given empty list");
    return false;
    }

  size_t cc;
  std::vector<size_t> removed;
  for ( cc = 2; cc < args.size(); ++ cc )
    {
    int item = atoi(args[cc].c_str());
    size_t nitem = varArgsExpanded.size();
    if ( item < 0 )
      {
      item = (int)nitem + item;
      }
    if ( item < 0 || nitem <= (size_t)item )
      {
      cmOStringStream str;
      str << "index: " << item << " out of range (-"
          << varArgsExpanded.size() << ", "
          << varArgsExpanded.size()-1 << ")";
      this->SetError(str.str().c_str());
      return false;
      }
    removed.push_back(static_cast<size_t>(item));
    }

  std::string value;
  const char* sep = "";
  for ( cc = 0; cc < varArgsExpanded.size(); ++ cc )
    {
    size_t kk;
    bool found = false;
    for ( kk = 0; kk < removed.size(); ++ kk )
      {
      if ( cc == removed[kk] )
        {
        found = true;
        }
      }

    if ( !found )
      {
      value += sep;
      value += varArgsExpanded[cc];
      sep = ";";
      }
    }

  this->Makefile->AddDefinition(listName.c_str(), value.c_str());
  return true;
}

