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

#include "cmake.h"
#include "cmTest.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmSourceFile.h"
#include "cmPropertyDefinition.h"

//----------------------------------------------------------------------------
cmGetPropertyCommand::cmGetPropertyCommand()
{
  this->InfoType = OutValue;
}

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

  // The cmake variable in which to store the result.
  this->Variable = args[0];

  // Get the scope from which to get the property.
  cmProperty::ScopeType scope;
  if(args[1] == "GLOBAL")
    {
    scope = cmProperty::GLOBAL;
    }
  else if(args[1] == "DIRECTORY")
    {
    scope = cmProperty::DIRECTORY;
    }
  else if(args[1] == "TARGET")
    {
    scope = cmProperty::TARGET;
    }
  else if(args[1] == "SOURCE")
    {
    scope = cmProperty::SOURCE_FILE;
    }
  else if(args[1] == "TEST")
    {
    scope = cmProperty::TEST;
    }
  else if(args[1] == "VARIABLE")
    {
    scope = cmProperty::VARIABLE;
    }
  else if(args[1] == "CACHE")
    {
    scope = cmProperty::CACHE;
    }
  else
    {
    cmOStringStream e;
    e << "given invalid scope " << args[1] << ".  "
      << "Valid scopes are "
      << "GLOBAL, DIRECTORY, TARGET, SOURCE, TEST, VARIABLE, CACHE.";
    this->SetError(e.str().c_str());
    return false;
    }

  // Parse remaining arguments.
  enum Doing { DoingNone, DoingName, DoingProperty, DoingType };
  Doing doing = DoingName;
  for(unsigned int i=2; i < args.size(); ++i)
    {
    if(args[i] == "PROPERTY")
      {
      doing = DoingProperty;
      }
    else if(args[i] == "BRIEF_DOCS")
      {
      doing = DoingNone;
      this->InfoType = OutBriefDoc;
      }
    else if(args[i] == "FULL_DOCS")
      {
      doing = DoingNone;
      this->InfoType = OutFullDoc;
      }
    else if(args[i] == "SET")
      {
      doing = DoingNone;
      this->InfoType = OutSet;
      }
    else if(args[i] == "DEFINED")
      {
      doing = DoingNone;
      this->InfoType = OutDefined;
      }
    else if(doing == DoingName)
      {
      doing = DoingNone;
      this->Name = args[i];
      }
    else if(doing == DoingProperty)
      {
      doing = DoingNone;
      this->PropertyName = args[i];
      }
    else
      {
      cmOStringStream e;
      e << "given invalid argument \"" << args[i] << "\".";
      this->SetError(e.str().c_str());
      return false;
      }
    }

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

  // Compute requested output.
  if(this->InfoType == OutBriefDoc)
    {
    // Lookup brief documentation.
    std::string output;
    if(cmPropertyDefinition* def =
       this->Makefile->GetCMakeInstance()->
       GetPropertyDefinition(this->PropertyName.c_str(), scope))
      {
      output = def->GetShortDescription();
      }
    else
      {
      output = "NOTFOUND";
      }
    this->Makefile->AddDefinition(this->Variable.c_str(), output.c_str());
    }
  else if(this->InfoType == OutFullDoc)
    {
    // Lookup full documentation.
    std::string output;
    if(cmPropertyDefinition* def =
       this->Makefile->GetCMakeInstance()->
       GetPropertyDefinition(this->PropertyName.c_str(), scope))
      {
      output = def->GetFullDescription();
      }
    else
      {
      output = "NOTFOUND";
      }
    this->Makefile->AddDefinition(this->Variable.c_str(), output.c_str());
    }
  else if(this->InfoType == OutDefined)
    {
    // Lookup if the property is defined
    if(this->Makefile->GetCMakeInstance()->
       GetPropertyDefinition(this->PropertyName.c_str(), scope))
      {
      this->Makefile->AddDefinition(this->Variable.c_str(), "1");
      }
    else
      {
      this->Makefile->AddDefinition(this->Variable.c_str(), "0");
      }
    }
  else
    {
    // Dispatch property getting.
    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::VARIABLE:    return this->HandleVariableMode();
      case cmProperty::CACHE:       return this->HandleCacheMode();

      case cmProperty::CACHED_VARIABLE:
        break; // should never happen
      }
    }

  return true;
}

//----------------------------------------------------------------------------
bool cmGetPropertyCommand::StoreResult(const char* value)
{
  if(this->InfoType == OutSet)
    {
    this->Makefile->AddDefinition(this->Variable.c_str(), value? "1":"0");
    }
  else // if(this->InfoType == OutValue)
    {
    if(value)
      {
      this->Makefile->AddDefinition(this->Variable.c_str(), value);
      }
    else
      {
      this->Makefile->RemoveDefinition(this->Variable.c_str());
      }
    }
  return true;
}

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

  // Get the property.
  cmake* cm = this->Makefile->GetCMakeInstance();
  return this->StoreResult(cm->GetProperty(this->PropertyName.c_str()));
}

//----------------------------------------------------------------------------
bool cmGetPropertyCommand::HandleDirectoryMode()
{
  // Default to the current directory.
  cmMakefile* mf = this->Makefile;

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

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

    // Lookup the generator.
    if(cmLocalGenerator* lg =
       (this->Makefile->GetLocalGenerator()
        ->GetGlobalGenerator()->FindLocalGenerator(dir.c_str())))
      {
      // 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;
      }
    }

  // Get the property.
  return this->StoreResult(mf->GetProperty(this->PropertyName.c_str()));
}

//----------------------------------------------------------------------------
bool cmGetPropertyCommand::HandleTargetMode()
{
  if(this->Name.empty())
    {
    this->SetError("not given name for TARGET scope.");
    return false;
    }

  if(this->PropertyName == "ALIASED_TARGET")
    {
    if(this->Makefile->IsAlias(this->Name))
      {
      if(cmTarget* target =
                          this->Makefile->FindTargetToUse(this->Name))
        {
        return this->StoreResult(target->GetName());
        }
      }
    return this->StoreResult((this->Variable + "-NOTFOUND").c_str());
    }
  if(cmTarget* target = this->Makefile->FindTargetToUse(this->Name))
    {
    return this->StoreResult(target->GetProperty(this->PropertyName.c_str(),
                                                 this->Makefile));
    }
  else
    {
    cmOStringStream e;
    e << "could not find TARGET " << this->Name
      << ".  Perhaps it has not yet been created.";
    this->SetError(e.str().c_str());
    return false;
    }
}

//----------------------------------------------------------------------------
bool cmGetPropertyCommand::HandleSourceMode()
{
  if(this->Name.empty())
    {
    this->SetError("not given name for SOURCE scope.");
    return false;
    }

  // Get the source file.
  if(cmSourceFile* sf =
     this->Makefile->GetOrCreateSource(this->Name.c_str()))
    {
    return
      this->StoreResult(sf->GetPropertyForUser(this->PropertyName.c_str()));
    }
  else
    {
    cmOStringStream e;
    e << "given SOURCE name that could not be found or created: "
      << this->Name;
    this->SetError(e.str().c_str());
    return false;
    }
}

//----------------------------------------------------------------------------
bool cmGetPropertyCommand::HandleTestMode()
{
  if(this->Name.empty())
    {
    this->SetError("not given name for TEST scope.");
    return false;
    }

  // Loop over all tests looking for matching names.
  if(cmTest* test = this->Makefile->GetTest(this->Name.c_str()))
    {
    return this->StoreResult(test->GetProperty(this->PropertyName.c_str()));
    }

  // If not found it is an error.
  cmOStringStream e;
  e << "given TEST name that does not exist: " << this->Name;
  this->SetError(e.str().c_str());
  return false;
}

//----------------------------------------------------------------------------
bool cmGetPropertyCommand::HandleVariableMode()
{
  if(!this->Name.empty())
    {
    this->SetError("given name for VARIABLE scope.");
    return false;
    }

  return this->StoreResult
    (this->Makefile->GetDefinition(this->PropertyName.c_str()));
}

//----------------------------------------------------------------------------
bool cmGetPropertyCommand::HandleCacheMode()
{
  if(this->Name.empty())
    {
    this->SetError("not given name for CACHE scope.");
    return false;
    }

  const char* value = 0;
  cmCacheManager::CacheIterator it =
    this->Makefile->GetCacheManager()->GetCacheIterator(this->Name.c_str());
  if(!it.IsAtEnd())
    {
    value = it.GetProperty(this->PropertyName.c_str());
    }
  this->StoreResult(value);
  return true;
}
