/*============================================================================
  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 "cmSetPropertyCommand.h"
#include "cmSetTargetPropertiesCommand.h"
#include "cmSetTestsPropertiesCommand.h"
#include "cmSetSourceFilesPropertiesCommand.h"


//----------------------------------------------------------------------------
cmSetPropertyCommand::cmSetPropertyCommand()
{
  this->AppendMode = false;
  this->AppendAsString = false;
  this->Remove = true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(args.size() < 2 )
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }

  // Get the scope on which to set the property.
  std::vector<std::string>::const_iterator arg = args.begin();
  cmProperty::ScopeType scope;
  if(*arg == "GLOBAL")
    {
    scope = cmProperty::GLOBAL;
    }
  else if(*arg == "DIRECTORY")
    {
    scope = cmProperty::DIRECTORY;
    }
  else if(*arg == "TARGET")
    {
    scope = cmProperty::TARGET;
    }
  else if(*arg == "SOURCE")
    {
    scope = cmProperty::SOURCE_FILE;
    }
  else if(*arg == "TEST")
    {
    scope = cmProperty::TEST;
    }
  else if(*arg == "CACHE")
    {
    scope = cmProperty::CACHE;
    }
  else if(*arg == "INSTALL")
    {
    scope = cmProperty::INSTALL;
    }
  else
    {
    std::ostringstream e;
    e << "given invalid scope " << *arg << ".  "
      << "Valid scopes are GLOBAL, DIRECTORY, "
        "TARGET, SOURCE, TEST, CACHE, INSTALL.";
    this->SetError(e.str());
    return false;
    }

  // Parse the rest of the arguments up to the values.
  enum Doing { DoingNone, DoingNames, DoingProperty, DoingValues };
  Doing doing = DoingNames;
  const char* sep = "";
  for(++arg; arg != args.end(); ++arg)
    {
    if(*arg == "PROPERTY")
      {
      doing = DoingProperty;
      }
    else if(*arg == "APPEND")
      {
      doing = DoingNone;
      this->AppendMode = true;
      this->Remove = false;
      this->AppendAsString = false;
      }
    else if(*arg == "APPEND_STRING")
      {
      doing = DoingNone;
      this->AppendMode = true;
      this->Remove = false;
      this->AppendAsString = true;
      }
    else if(doing == DoingNames)
      {
      this->Names.insert(*arg);
      }
    else if(doing == DoingProperty)
      {
      this->PropertyName = *arg;
      doing = DoingValues;
      }
    else if(doing == DoingValues)
      {
      this->PropertyValue += sep;
      sep = ";";
      this->PropertyValue += *arg;
      this->Remove = false;
      }
    else
      {
      std::ostringstream e;
      e << "given invalid argument \"" << *arg << "\".";
      this->SetError(e.str());
      return false;
      }
    }

  // Make sure a property name was found.
  if(this->PropertyName.empty())
    {
    this->SetError("not given a PROPERTY <name> argument.");
    return false;
    }

  // Dispatch property setting.
  switch(scope)
    {
    case cmProperty::GLOBAL:      return this->HandleGlobalMode();
    case cmProperty::DIRECTORY:   return this->HandleDirectoryMode();
    case cmProperty::TARGET:      return this->HandleTargetMode();
    case cmProperty::SOURCE_FILE: return this->HandleSourceMode();
    case cmProperty::TEST:        return this->HandleTestMode();
    case cmProperty::CACHE:       return this->HandleCacheMode();
    case cmProperty::INSTALL:     return this->HandleInstallMode();

    case cmProperty::VARIABLE:
    case cmProperty::CACHED_VARIABLE:
      break; // should never happen
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleGlobalMode()
{
  if(!this->Names.empty())
    {
    this->SetError("given names for GLOBAL scope.");
    return false;
    }

  // Set or append the property.
  cmake* cm = this->Makefile->GetCMakeInstance();
  const char* name = this->PropertyName.c_str();
  const char *value = this->PropertyValue.c_str();
  if (this->Remove)
    {
    value = 0;
    }
  if(this->AppendMode)
    {
    cm->AppendProperty(name, value ? value : "", this->AppendAsString);
    }
  else
    {
    cm->SetProperty(name, value);
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleDirectoryMode()
{
  if(this->Names.size() > 1)
    {
    this->SetError("allows at most one name for DIRECTORY scope.");
    return false;
    }

  // Default to the current directory.
  cmMakefile* mf = this->Makefile;

  // Lookup the directory if given.
  if(!this->Names.empty())
    {
    // Construct the directory name.  Interpret relative paths with
    // respect to the current directory.
    std::string dir = *this->Names.begin();
    if(!cmSystemTools::FileIsFullPath(dir.c_str()))
      {
      dir = this->Makefile->GetCurrentSourceDirectory();
      dir += "/";
      dir += *this->Names.begin();
      }

    // The local generators are associated with collapsed paths.
    dir = cmSystemTools::CollapseFullPath(dir);

    mf = this->Makefile->GetGlobalGenerator()->FindMakefile(dir);
    if (!mf)
      {
      // Could not find the directory.
      this->SetError
        ("DIRECTORY scope provided but requested directory was not found. "
         "This could be because the directory argument was invalid or, "
         "it is valid but has not been processed yet.");
      return false;
      }
    }

  // Set or append the property.
  const char* name = this->PropertyName.c_str();
  const char *value = this->PropertyValue.c_str();
  if (this->Remove)
    {
    value = 0;
    }
  if(this->AppendMode)
    {
    mf->AppendProperty(name, value ? value : "", this->AppendAsString);
    }
  else
    {
    mf->SetProperty(name, value);
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleTargetMode()
{
  for(std::set<std::string>::const_iterator ni = this->Names.begin();
      ni != this->Names.end(); ++ni)
    {
    if (this->Makefile->IsAlias(*ni))
      {
      this->SetError("can not be used on an ALIAS target.");
      return false;
      }
    if(cmTarget* target = this->Makefile->FindTargetToUse(*ni))
      {
      // Handle the current target.
      if(!this->HandleTarget(target))
        {
        return false;
        }
      }
    else
      {
      std::ostringstream e;
      e << "could not find TARGET " << *ni
        << ".  Perhaps it has not yet been created.";
      this->SetError(e.str());
      return false;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleTarget(cmTarget* target)
{
  // Set or append the property.
  const char* name = this->PropertyName.c_str();
  const char *value = this->PropertyValue.c_str();
  if (this->Remove)
    {
    value = 0;
    }
  if(this->AppendMode)
    {
    target->AppendProperty(name, value, this->AppendAsString);
    }
  else
    {
    target->SetProperty(name, value);
    }

  // Check the resulting value.
  target->CheckProperty(name, this->Makefile);

  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleSourceMode()
{
  for(std::set<std::string>::const_iterator ni = this->Names.begin();
      ni != this->Names.end(); ++ni)
    {
    // Get the source file.
    if(cmSourceFile* sf = this->Makefile->GetOrCreateSource(*ni))
      {
      if(!this->HandleSource(sf))
        {
        return false;
        }
      }
    else
      {
      std::ostringstream e;
      e << "given SOURCE name that could not be found or created: " << *ni;
      this->SetError(e.str());
      return false;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleSource(cmSourceFile* sf)
{
  // Set or append the property.
  const char* name = this->PropertyName.c_str();
  const char *value = this->PropertyValue.c_str();
  if (this->Remove)
    {
    value = 0;
    }

  if(this->AppendMode)
    {
    sf->AppendProperty(name, value, this->AppendAsString);
    }
  else
    {
    sf->SetProperty(name, value);
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleTestMode()
{
  // Look for tests with all names given.
  std::set<std::string>::iterator next;
  for(std::set<std::string>::iterator ni = this->Names.begin();
      ni != this->Names.end(); ni = next)
    {
    next = ni;
    ++next;
    if(cmTest* test = this->Makefile->GetTest(*ni))
      {
      if(this->HandleTest(test))
        {
        this->Names.erase(ni);
        }
      else
        {
        return false;
        }
      }
    }

  // Names that are still left were not found.
  if(!this->Names.empty())
    {
    std::ostringstream e;
    e << "given TEST names that do not exist:\n";
    for(std::set<std::string>::const_iterator ni = this->Names.begin();
        ni != this->Names.end(); ++ni)
      {
      e << "  " << *ni << "\n";
      }
    this->SetError(e.str());
    return false;
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleTest(cmTest* test)
{
  // Set or append the property.
  const char* name = this->PropertyName.c_str();
  const char *value = this->PropertyValue.c_str();
  if (this->Remove)
    {
    value = 0;
    }
  if(this->AppendMode)
    {
    test->AppendProperty(name, value, this->AppendAsString);
    }
  else
    {
    test->SetProperty(name, value);
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleCacheMode()
{
  if(this->PropertyName == "ADVANCED")
    {
    if(!this->Remove &&
       !cmSystemTools::IsOn(this->PropertyValue.c_str()) &&
       !cmSystemTools::IsOff(this->PropertyValue.c_str()))
      {
      std::ostringstream e;
      e << "given non-boolean value \"" << this->PropertyValue
        << "\" for CACHE property \"ADVANCED\".  ";
      this->SetError(e.str());
      return false;
      }
    }
  else if(this->PropertyName == "TYPE")
    {
    if(!cmState::IsCacheEntryType(this->PropertyValue.c_str()))
      {
      std::ostringstream e;
      e << "given invalid CACHE entry TYPE \"" << this->PropertyValue << "\"";
      this->SetError(e.str());
      return false;
      }
    }
  else if(this->PropertyName != "HELPSTRING" &&
          this->PropertyName != "STRINGS" &&
          this->PropertyName != "VALUE")
    {
    std::ostringstream e;
    e << "given invalid CACHE property " << this->PropertyName << ".  "
      << "Settable CACHE properties are: "
      << "ADVANCED, HELPSTRING, STRINGS, TYPE, and VALUE.";
    this->SetError(e.str());
    return false;
    }

  for(std::set<std::string>::const_iterator ni = this->Names.begin();
      ni != this->Names.end(); ++ni)
    {
    // Get the source file.
    cmMakefile* mf = this->GetMakefile();
    cmake* cm = mf->GetCMakeInstance();
    const char* existingValue
                          = cm->GetState()->GetCacheEntryValue(*ni);
    if(existingValue)
      {
      if(!this->HandleCacheEntry(*ni))
        {
        return false;
        }
      }
    else
      {
      std::ostringstream e;
      e << "could not find CACHE variable " << *ni
        << ".  Perhaps it has not yet been created.";
      this->SetError(e.str());
      return false;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleCacheEntry(std::string const& cacheKey)
{
  // Set or append the property.
  const char* name = this->PropertyName.c_str();
  const char* value = this->PropertyValue.c_str();
  cmState* state = this->Makefile->GetState();
  if (this->Remove)
    {
    state->RemoveCacheEntryProperty(cacheKey, name);
    }
  if(this->AppendMode)
    {
    state->AppendCacheEntryProperty(cacheKey, name, value,
                                     this->AppendAsString);
    }
  else
    {
    state->SetCacheEntryProperty(cacheKey, name, value);
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleInstallMode()
{
  cmake* cm = this->Makefile->GetCMakeInstance();

  for(std::set<std::string>::const_iterator i = this->Names.begin();
      i != this->Names.end(); ++i)
    {
    if(cmInstalledFile* file = cm->GetOrCreateInstalledFile(
      this->Makefile, *i))
      {
      if(!this->HandleInstall(file))
        {
        return false;
        }
      }
    else
      {
      std::ostringstream e;
      e << "given INSTALL name that could not be found or created: " << *i;
      this->SetError(e.str());
      return false;
      }
    }
  return true;
}

//----------------------------------------------------------------------------
bool cmSetPropertyCommand::HandleInstall(cmInstalledFile* file)
{
  // Set or append the property.
  std::string const& name = this->PropertyName;

  cmMakefile* mf = this->Makefile;

  const char *value = this->PropertyValue.c_str();
  if (this->Remove)
    {
    file->RemoveProperty(name);
    }
  else if(this->AppendMode)
    {
    file->AppendProperty(mf, name, value, this->AppendAsString);
    }
  else
    {
    file->SetProperty(mf, name, value);
    }
  return true;
}
