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

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile: cmExportFileGenerator.cxx,v $
  Language:  C++
  Date:      $Date: 2012/03/29 17:21:09 $
  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 "cmExportFileGenerator.h"

#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmVersion.h"

#include <cmsys/auto_ptr.hxx>

//----------------------------------------------------------------------------
cmExportFileGenerator::cmExportFileGenerator()
{
  this->AppendMode = false;
}

//----------------------------------------------------------------------------
void cmExportFileGenerator::AddConfiguration(const char* config)
{
  this->Configurations.push_back(config);
}

//----------------------------------------------------------------------------
void cmExportFileGenerator::SetExportFile(const char* mainFile)
{
  this->MainImportFile = mainFile;
  this->FileDir =
    cmSystemTools::GetFilenamePath(this->MainImportFile);
  this->FileBase =
    cmSystemTools::GetFilenameWithoutLastExtension(this->MainImportFile);
  this->FileExt =
    cmSystemTools::GetFilenameLastExtension(this->MainImportFile);
}

//----------------------------------------------------------------------------
bool cmExportFileGenerator::GenerateImportFile()
{
  // Open the output file to generate it.
  cmsys::auto_ptr<std::ofstream> foutPtr;
  if(this->AppendMode)
    {
    // Open for append.
    cmsys::auto_ptr<std::ofstream>
      ap(new std::ofstream(this->MainImportFile.c_str(), std::ios::app));
    foutPtr = ap;
    }
  else
    {
    // Generate atomically and with copy-if-different.
    cmsys::auto_ptr<cmGeneratedFileStream>
      ap(new cmGeneratedFileStream(this->MainImportFile.c_str(), true));
    ap->SetCopyIfDifferent(true);
    foutPtr = ap;
    }
  if(!foutPtr.get() || !*foutPtr)
    {
    std::string se = cmSystemTools::GetLastSystemError();
    cmOStringStream e;
    e << "cannot write to file \"" << this->MainImportFile
      << "\": " << se;
    cmSystemTools::Error(e.str().c_str());
    return false;
    }
  std::ostream& os = *foutPtr;

  // Protect that file against use with older CMake versions.
  os << "# Generated by CMake " << cmVersion::GetCMakeVersion() << "\n\n";
  os << "IF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n"
     << "   MESSAGE(FATAL_ERROR \"CMake >= 2.6.0 required\")\n"
     << "ENDIF(\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" LESS 2.5)\n";

  // Isolate the file policy level.
  // We use 2.6 here instead of the current version because newer
  // versions of CMake should be able to export files imported by 2.6
  // until the import format changes.
  os << "CMAKE_POLICY(PUSH)\n"
     << "CMAKE_POLICY(VERSION 2.6)\n";

  // Start with the import file header.
  this->GenerateImportHeaderCode(os);

  // Create all the imported targets.
  bool result = this->GenerateMainFile(os);

  // End with the import file footer.
  this->GenerateImportFooterCode(os);
  os << "CMAKE_POLICY(POP)\n";

  return result;
}

//----------------------------------------------------------------------------
void cmExportFileGenerator::GenerateImportConfig(std::ostream& os,
                                                 const char* config)
{
  // Construct the property configuration suffix.
  std::string suffix = "_";
  if(config && *config)
    {
    suffix += cmSystemTools::UpperCase(config);
    }
  else
    {
    suffix += "NOCONFIG";
    }

  // Generate the per-config target information.
  this->GenerateImportTargetsConfig(os, config, suffix);
}

//----------------------------------------------------------------------------
void
cmExportFileGenerator
::SetImportDetailProperties(const char* config, std::string const& suffix,
                            cmTarget* target, ImportPropertyMap& properties)
{
  // Get the makefile in which to lookup target information.
  cmMakefile* mf = target->GetMakefile();

  // Add the soname for unix shared libraries.
  if(target->GetType() == cmTarget::SHARED_LIBRARY ||
     target->GetType() == cmTarget::MODULE_LIBRARY)
    {
    // Check whether this is a DLL platform.
    bool dll_platform =
      (mf->IsOn("WIN32") || mf->IsOn("CYGWIN") || mf->IsOn("MINGW"));
    if(!dll_platform)
      {
      std::string soname = target->GetSOName(config);
      std::string prop = "IMPORTED_SONAME";
      prop += suffix;
      properties[prop] = soname;
      }
    }

  // Add the transitive link dependencies for this configuration.
  if(cmTargetLinkInterface const* iface =
     target->GetLinkInterface(config))
    {
    // This target provides a link interface, so use it.
    this->SetImportLinkProperty(suffix, target,
                                "IMPORTED_LINK_INTERFACE_LIBRARIES",
                                iface->Libraries, properties);
    this->SetImportLinkProperty(suffix, target,
                                "IMPORTED_LINK_DEPENDENT_LIBRARIES",
                                iface->SharedDeps, properties);
    }
  else if(target->GetType() == cmTarget::STATIC_LIBRARY ||
          target->GetType() == cmTarget::SHARED_LIBRARY)
    {
    // The default link interface for static and shared libraries is
    // their link implementation library list.
    this->SetImportLinkProperties(config, suffix, target, properties);
    }
}

//----------------------------------------------------------------------------
void
cmExportFileGenerator
::SetImportLinkProperties(const char* config, std::string const& suffix,
                          cmTarget* target, ImportPropertyMap& properties)
{
  // Compute which library configuration to link.
  cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED;
  if(config && cmSystemTools::UpperCase(config) == "DEBUG")
    {
    linkType = cmTarget::DEBUG;
    }

  // Construct the list of libs linked for this configuration.
  std::vector<std::string> actual_libs;
  cmTarget::LinkLibraryVectorType const& libs =
    target->GetOriginalLinkLibraries();
  for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
      li != libs.end(); ++li)
    {
    // Skip entries that will resolve to the target itself, are empty,
    // or are not meant for this configuration.
    if(li->first == target->GetName() || li->first.empty() ||
       !(li->second == cmTarget::GENERAL || li->second == linkType))
      {
      continue;
      }

    // Store this entry.
    actual_libs.push_back(li->first);
    }

  // Store the entries in the property.
  this->SetImportLinkProperty(suffix, target,
                              "IMPORTED_LINK_INTERFACE_LIBRARIES",
                              actual_libs, properties);
}

//----------------------------------------------------------------------------
void
cmExportFileGenerator
::SetImportLinkProperty(std::string const& suffix,
                        cmTarget* target,
                        const char* propName,
                        std::vector<std::string> const& libs,
                        ImportPropertyMap& properties)
{
  // Skip the property if there are no libraries.
  if(libs.empty())
    {
    return;
    }

  // Get the makefile in which to lookup target information.
  cmMakefile* mf = target->GetMakefile();

  // Construct the property value.
  std::string link_libs;
  const char* sep = "";
  for(std::vector<std::string>::const_iterator li = libs.begin();
      li != libs.end(); ++li)
    {
    // Separate this from the previous entry.
    link_libs += sep;
    sep = ";";

    // Append this entry.
    if(cmTarget* tgt = mf->FindTargetToUse(li->c_str()))
      {
      // This is a target.
      if(tgt->IsImported())
        {
        // The target is imported (and therefore is not in the
        // export).  Append the raw name.
        link_libs += *li;
        }
      else if(this->ExportedTargets.find(tgt) != this->ExportedTargets.end())
        {
        // The target is in the export.  Append it with the export
        // namespace.
        link_libs += this->Namespace;
        link_libs += *li;
        }
      else
        {
        // The target is not in the export.
        if(!this->AppendMode)
          {
          // We are not appending, so all exported targets should be
          // known here.  This is probably user-error.
          this->ComplainAboutMissingTarget(target, tgt);
          }
        // Assume the target will be exported by another command.
        // Append it with the export namespace.
        link_libs += this->Namespace;
        link_libs += *li;
        }
      }
    else
      {
      // Append the raw name.
      link_libs += *li;
      }
    }

  // Store the property.
  std::string prop = propName;
  prop += suffix;
  properties[prop] = link_libs;
}

//----------------------------------------------------------------------------
void cmExportFileGenerator::GenerateImportHeaderCode(std::ostream& os,
                                                     const char* config)
{
  os << "#----------------------------------------------------------------\n"
     << "# Generated CMake target import file";
  if(config)
    {
    os << " for configuration \"" << config << "\".\n";
    }
  else
    {
    os << ".\n";
    }
  os << "#----------------------------------------------------------------\n"
     << "\n";
  this->GenerateImportVersionCode(os);
}

//----------------------------------------------------------------------------
void cmExportFileGenerator::GenerateImportFooterCode(std::ostream& os)
{
  os << "# Commands beyond this point should not need to know the version.\n"
     << "SET(CMAKE_IMPORT_FILE_VERSION)\n";
}

//----------------------------------------------------------------------------
void cmExportFileGenerator::GenerateImportVersionCode(std::ostream& os)
{
  // Store an import file format version.  This will let us change the
  // format later while still allowing old import files to work.
  os << "# Commands may need to know the format version.\n"
     << "SET(CMAKE_IMPORT_FILE_VERSION 1)\n"
     << "\n";
}

//----------------------------------------------------------------------------
void
cmExportFileGenerator
::GenerateImportTargetCode(std::ostream& os, cmTarget* target)
{
  // Construct the imported target name.
  std::string targetName = this->Namespace;
  targetName += target->GetName();

  // Create the imported target.
  os << "# Create imported target " << targetName << "\n";
  switch(target->GetType())
    {
    case cmTarget::EXECUTABLE:
      os << "ADD_EXECUTABLE(" << targetName << " IMPORTED)\n";
      break;
    case cmTarget::STATIC_LIBRARY:
      os << "ADD_LIBRARY(" << targetName << " STATIC IMPORTED)\n";
      break;
    case cmTarget::SHARED_LIBRARY:
      os << "ADD_LIBRARY(" << targetName << " SHARED IMPORTED)\n";
      break;
    case cmTarget::MODULE_LIBRARY:
      os << "ADD_LIBRARY(" << targetName << " MODULE IMPORTED)\n";
      break;
    default:  // should never happen
      break;
    }

  // Mark the imported executable if it has exports.
  if(target->IsExecutableWithExports())
    {
    os << "SET_PROPERTY(TARGET " << targetName
       << " PROPERTY ENABLE_EXPORTS 1)\n";
    }

  // Mark the imported library if it is a framework.
  if(target->IsFrameworkOnApple())
    {
    os << "SET_PROPERTY(TARGET " << targetName
       << " PROPERTY FRAMEWORK 1)\n";
    }

  // Mark the imported executable if it is an application bundle.
  if(target->IsAppBundleOnApple())
    {
    os << "SET_PROPERTY(TARGET " << targetName
       << " PROPERTY MACOSX_BUNDLE 1)\n";
    }
  os << "\n";
}

//----------------------------------------------------------------------------
void
cmExportFileGenerator
::GenerateImportPropertyCode(std::ostream& os, const char* config,
                             cmTarget* target,
                             ImportPropertyMap const& properties)
{
  // Construct the imported target name.
  std::string targetName = this->Namespace;
  targetName += target->GetName();

  // Set the import properties.
  os << "# Import target \"" << targetName << "\" for configuration \""
     << config << "\"\n";
  os << "SET_PROPERTY(TARGET " << targetName
     << " APPEND PROPERTY IMPORTED_CONFIGURATIONS ";
  if(config && *config)
    {
    os << cmSystemTools::UpperCase(config);
    }
  else
    {
    os << "NOCONFIG";
    }
  os << ")\n";
  os << "SET_TARGET_PROPERTIES(" << targetName << " PROPERTIES\n";
  for(ImportPropertyMap::const_iterator pi = properties.begin();
      pi != properties.end(); ++pi)
    {
    os << "  " << pi->first << " \"" << pi->second << "\"\n";
    }
  os << "  )\n"
     << "\n";
}
