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

#include "cmExportSet.h"
#include "cmGeneratedFileStream.h"
#include "cmGlobalGenerator.h"
#include "cmInstallExportGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmTargetExport.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,
                            std::vector<std::string>& missingTargets
                           )
{
  // 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 prop;
      std::string value;
      if(target->HasSOName(config))
        {
        prop = "IMPORTED_SONAME";
        value = target->GetSOName(config);
        }
      else
        {
        prop = "IMPORTED_NO_SONAME";
        value = "TRUE";
        }
      prop += suffix;
      properties[prop] = value;
      }
    }

  // Add the transitive link dependencies for this configuration.
  if(cmTarget::LinkInterface const* iface = target->GetLinkInterface(config))
    {
    this->SetImportLinkProperty(suffix, target,
                                "IMPORTED_LINK_INTERFACE_LANGUAGES",
                                iface->Languages, properties, missingTargets);
    this->SetImportLinkProperty(suffix, target,
                                "IMPORTED_LINK_INTERFACE_LIBRARIES",
                                iface->Libraries, properties, missingTargets);
    this->SetImportLinkProperty(suffix, target,
                                "IMPORTED_LINK_DEPENDENT_LIBRARIES",
                                iface->SharedDeps, properties, missingTargets);
    if(iface->Multiplicity > 0)
      {
      std::string prop = "IMPORTED_LINK_INTERFACE_MULTIPLICITY";
      prop += suffix;
      cmOStringStream m;
      m << iface->Multiplicity;
      properties[prop] = m.str();
      }
    }
}

//----------------------------------------------------------------------------
void
cmExportFileGenerator
::SetImportLinkProperty(std::string const& suffix,
                        cmTarget* target,
                        const char* propName,
                        std::vector<std::string> const& libs,
                        ImportPropertyMap& properties,
                        std::vector<std::string>& missingTargets
                       )
{
  // 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
        {
        this->HandleMissingTarget(link_libs, missingTargets, mf, target, tgt);
        }
      }
    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";
    }

  if (target->IsCFBundleOnApple())
    {
    os << "SET_PROPERTY(TARGET " << targetName
       << " PROPERTY 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";
}


//----------------------------------------------------------------------------
void cmExportFileGenerator::GenerateMissingTargetsCheckCode(std::ostream& os,
                                const std::vector<std::string>& missingTargets)
{
  os << "# Make sure the targets which have been exported in some other \n"
        "# export set exist.\n";
  for(unsigned int i=0; i<missingTargets.size(); ++i)
    {
    os << "IF(NOT TARGET \"" << missingTargets[i] << "\" )\n"
       << "  IF(CMAKE_FIND_PACKAGE_NAME)\n"
       << "    SET( ${CMAKE_FIND_PACKAGE_NAME}_FOUND FALSE)\n"
       << "    SET( ${CMAKE_FIND_PACKAGE_NAME}_NOT_FOUND_MESSAGE "
       << "\"Required imported target \\\"" << missingTargets[i]
       << "\\\" not found ! \")\n"
       << "  ELSE()\n"
       << "    MESSAGE(FATAL_ERROR \"Required imported target \\\""
       << missingTargets[i] << "\\\" not found ! \")\n"
       << "  ENDIF()\n"
       << "ENDIF()\n";
    }
  os << "\n";
}


//----------------------------------------------------------------------------
void
cmExportFileGenerator::GenerateImportedFileCheckLoop(std::ostream& os)
{
  // Add code which verifies at cmake time that the file which is being
  // imported actually exists on disk. This should in theory always be theory
  // case, but still when packages are split into normal and development
  // packages this might get broken (e.g. the Config.cmake could be part of
  // the non-development package, something similar happened to me without
  // on SUSE with a mysql pkg-config file, which claimed everything is fine,
  // but the development package was not installed.).
  os << "# Loop over all imported files and verify that they actually exist\n"
        "FOREACH(target ${_IMPORT_CHECK_TARGETS} )\n"
        "  FOREACH(file ${_IMPORT_CHECK_FILES_FOR_${target}} )\n"
        "    IF(NOT EXISTS \"${file}\" )\n"
        "      MESSAGE(FATAL_ERROR \"The imported target \\\"${target}\\\""
        " references the file\n"
        "   \\\"${file}\\\"\n"
        "but this file does not exist.  Possible reasons include:\n"
        "* The file was deleted, renamed, or moved to another location.\n"
        "* An install or uninstall procedure did not complete successfully.\n"
        "* The installation package was faulty and contained\n"
        "   \\\"${CMAKE_CURRENT_LIST_FILE}\\\"\n"
        "but not all the files it references.\n"
        "\")\n"
        "    ENDIF()\n"
        "  ENDFOREACH()\n"
        "  UNSET(_IMPORT_CHECK_FILES_FOR_${target})\n"
        "ENDFOREACH()\n"
        "UNSET(_IMPORT_CHECK_TARGETS)\n"
        "\n";
}


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

  os << "LIST(APPEND _IMPORT_CHECK_TARGETS " << targetName << " )\n"
        "LIST(APPEND _IMPORT_CHECK_FILES_FOR_" << targetName << " ";

  for(std::set<std::string>::const_iterator li = importedLocations.begin();
      li != importedLocations.end();
      ++li)
    {
    ImportPropertyMap::const_iterator pi = properties.find(*li);
    if (pi != properties.end())
      {
      os << "\"" << pi->second << "\" ";
      }
    }

  os << ")\n\n";
}
