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

#include "cmCacheManager.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->GetCurrentDirectory();
      dir += "/";
      dir += *this->Names.begin();
      }

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

    // Lookup the generator.
    if(cmLocalGenerator* lg =
       (this->Makefile->GetLocalGenerator()
        ->GetGlobalGenerator()->FindLocalGenerator(dir)))
      {
      // Use the makefile for the directory found.
      mf = lg->GetMakefile();
      }
    else
      {
      // 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(!cmCacheManager::IsType(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();
    cmCacheManager::CacheIterator it =
      cm->GetCacheManager()->GetCacheIterator(ni->c_str());
    if(!it.IsAtEnd())
      {
      if(!this->HandleCacheEntry(it))
        {
        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(cmCacheManager::CacheIterator& it)
{
  // 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)
    {
    it.AppendProperty(name, value, this->AppendAsString);
    }
  else
    {
    it.SetProperty(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;
}
