/*=========================================================================

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmExportCommand.cxx,v $
  Language:  C++
  Date:      $Date: 2012/03/29 17:21:08 $
  Version:   $Revision: 1.1.1.1 $

  Copyright (c) 2002 Kitware, Inc., Insight Consortium.  All rights reserved.
  See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#include "cmExportCommand.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmake.h"

#include "cmExportBuildFileGenerator.h"

cmExportCommand::cmExportCommand()
:cmCommand()
,ArgumentGroup()
,Targets(&Helper, "TARGETS")
,Append(&Helper, "APPEND", &ArgumentGroup)
,Namespace(&Helper, "NAMESPACE", &ArgumentGroup)
,Filename(&Helper, "FILE", &ArgumentGroup)
{
  // at first TARGETS
  this->Targets.Follows(0);
  // and after that the other options in any order
  this->ArgumentGroup.Follows(&this->Targets);
}


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

  std::vector<std::string> unknownArgs;
  this->Helper.Parse(&args, &unknownArgs);

  if (!unknownArgs.empty())
    {
    this->SetError("Unknown arguments.");
    return false;
    }

  if (this->Targets.WasFound() == false)
    {
    this->SetError("TARGETS option missing.");
    return false;
    }

  if(!this->Filename.WasFound())
    {
    this->SetError("FILE <filename> option missing.");
    return false;
    }

  // Make sure the file has a .cmake extension.
  if(cmSystemTools::GetFilenameLastExtension(this->Filename.GetCString())
     != ".cmake")
    {
    cmOStringStream e;
    e << "FILE option given filename \"" << this->Filename.GetString()
      << "\" which does not have an extension of \".cmake\".\n";
    this->SetError(e.str().c_str());
    return false;
    }

  // Get the file to write.
  std::string fname = this->Filename.GetString();
  if(cmSystemTools::FileIsFullPath(fname.c_str()))
    {
    if(!this->Makefile->CanIWriteThisFile(fname.c_str()))
      {
      cmOStringStream e;
      e << "FILE option given filename \"" << fname
        << "\" which is in the source tree.\n";
      this->SetError(e.str().c_str());
      return false;
      }
    }
  else
    {
    // Interpret relative paths with respect to the current build dir.
    fname = this->Makefile->GetCurrentOutputDirectory();
    fname += "/";
    fname += this->Filename.GetString();
    }

  // Collect the targets to be exported.
  std::vector<cmTarget*> targets;
  for(std::vector<std::string>::const_iterator
      currentTarget = this->Targets.GetVector().begin();
      currentTarget != this->Targets.GetVector().end();
      ++currentTarget)
    {
    if(cmTarget* target =
       this->Makefile->GetLocalGenerator()->
       GetGlobalGenerator()->FindTarget(0, currentTarget->c_str()))
      {
      if((target->GetType() == cmTarget::EXECUTABLE) ||
         (target->GetType() == cmTarget::STATIC_LIBRARY) ||
         (target->GetType() == cmTarget::SHARED_LIBRARY) ||
         (target->GetType() == cmTarget::MODULE_LIBRARY))
        {
        targets.push_back(target);
        }
      else
        {
        cmOStringStream e;
        e << "given target \"" << *currentTarget
          << "\" which is not an executable or library.";
        this->SetError(e.str().c_str());
        return false;
        }
      }
    else
      {
      cmOStringStream e;
      e << "given target \"" << *currentTarget
        << "\" which is not built by this project.";
      this->SetError(e.str().c_str());
      return false;
      }
    }

  // Setup export file generation.
  cmExportBuildFileGenerator ebfg;
  ebfg.SetExportFile(fname.c_str());
  ebfg.SetNamespace(this->Namespace.GetCString());
  ebfg.SetAppendMode(this->Append.IsEnabled());
  ebfg.SetExports(&targets);
  ebfg.SetCommand(this);

  // Compute the set of configurations exported.
  if(const char* types =
     this->Makefile->GetDefinition("CMAKE_CONFIGURATION_TYPES"))
    {
    std::vector<std::string> configurationTypes;
    cmSystemTools::ExpandListArgument(types, configurationTypes);
    for(std::vector<std::string>::const_iterator
          ci = configurationTypes.begin();
        ci != configurationTypes.end(); ++ci)
      {
      ebfg.AddConfiguration(ci->c_str());
      }
    }
  else if(const char* config =
          this->Makefile->GetDefinition("CMAKE_BUILD_TYPE"))
    {
    ebfg.AddConfiguration(config);
    }
  else
    {
    ebfg.AddConfiguration("");
    }

  // Generate the import file.
  if(!ebfg.GenerateImportFile() && this->ErrorMessage.empty())
    {
    this->SetError("could not write export file.");
    return false;
    }

  // Report generated error message if any.
  if(!this->ErrorMessage.empty())
    {
    this->SetError(this->ErrorMessage.c_str());
    return false;
    }

  return true;
}
