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

  Program:   CMake - Cross-Platform Makefile Generator
  Module:    $RCSfile$
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  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 "cmInstallTargetGenerator.h"

#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmTarget.h"
#include "cmake.h"

//----------------------------------------------------------------------------
cmInstallTargetGenerator
::cmInstallTargetGenerator(cmTarget& t, const char* dest, bool implib,
                           const char* file_permissions,
                           std::vector<std::string> const& configurations,
                           const char* component, bool optional):
  Target(&t), Destination(dest), ImportLibrary(implib),
  FilePermissions(file_permissions), Configurations(configurations),
  Component(component), Optional(optional)
{
  this->Target->SetHaveInstallRule(true);
}

//----------------------------------------------------------------------------
cmInstallTargetGenerator
::~cmInstallTargetGenerator()
{
}

//----------------------------------------------------------------------------
void cmInstallTargetGenerator::GenerateScript(std::ostream& os)
{
  // Compute the build tree directory from which to copy the target.
  std::string fromDir;
  if(this->Target->NeedRelinkBeforeInstall())
    {
    fromDir = this->Target->GetMakefile()->GetStartOutputDirectory();
    fromDir += cmake::GetCMakeFilesDirectory();
    fromDir += "/CMakeRelink.dir/";
    }
  else
    {
    fromDir = this->Target->GetDirectory();
    fromDir += "/";
    }

  // Write variable settings to do per-configuration references.
  this->PrepareScriptReference(os, this->Target, "BUILD", true, false);

  // Create the per-configuration reference.
  std::string fromName = this->GetScriptReference(this->Target, "BUILD",
                                                  false);
  std::string fromFile = fromDir;
  fromFile += fromName;

  // Choose the final destination.  This may be modified for certain
  // target types.
  std::string destination = this->Destination;

  // Setup special properties for some target types.
  std::string literal_args;
  std::string props;
  const char* properties = 0;
  cmTarget::TargetType type = this->Target->GetType();
  switch(type)
    {
    case cmTarget::SHARED_LIBRARY:
      {
      // Add shared library installation properties if this platform
      // supports them.
      const char* lib_version = 0;
      const char* lib_soversion = 0;

        // Versioning is supported only for shared libraries and modules,
        // and then only when the platform supports an soname flag.
      cmGlobalGenerator* gg =
        (this->Target->GetMakefile()
         ->GetLocalGenerator()->GetGlobalGenerator());
      if(const char* linkLanguage = this->Target->GetLinkerLanguage(gg))
        {
        std::string sonameFlagVar = "CMAKE_SHARED_LIBRARY_SONAME_";
        sonameFlagVar += linkLanguage;
        sonameFlagVar += "_FLAG";
        if(this->Target->GetMakefile()->GetDefinition(sonameFlagVar.c_str()))
          {
          lib_version = this->Target->GetProperty("VERSION");
          lib_soversion = this->Target->GetProperty("SOVERSION");
        }
        }

      if(lib_version)
        {
        props += " VERSION ";
        props += lib_version;
        }
      if(lib_soversion)
        {
        props += " SOVERSION ";
        props += lib_soversion;
        }
      properties = props.c_str();
      }
      break;
    case cmTarget::EXECUTABLE:
      {
      // Add executable installation properties if this platform
      // supports them.
#if defined(_WIN32) && !defined(__CYGWIN__)
      const char* exe_version = 0;
#else
      const char* exe_version = this->Target->GetProperty("VERSION");
#endif
      if(exe_version)
        {
        props += " VERSION ";
        props += exe_version;
        properties = props.c_str();
        }

      // Handle OSX Bundles.
      if(this->Target->GetMakefile()->IsOn("APPLE") &&
         this->Target->GetPropertyAsBool("MACOSX_BUNDLE"))
        {
        // Compute the source locations of the bundle executable and
        // Info.plist file.
        this->PrepareScriptReference(os, this->Target, "INSTALL",
                                     false, false);
        fromFile += ".app";
        type = cmTarget::INSTALL_DIRECTORY;
        literal_args += " USE_SOURCE_PERMISSIONS";
        }
      }
      break;
    case cmTarget::STATIC_LIBRARY:
    case cmTarget::MODULE_LIBRARY:
      // Nothing special for modules or static libraries.
      break;
    default:
      break;
    }

  // An import library looks like a static library.
  if(this->ImportLibrary)
    {
    type = cmTarget::STATIC_LIBRARY;
    }

  // Write code to install the target file.
  const char* no_dir_permissions = 0;
  const char* no_rename = 0;
  bool optional = this->Optional | this->ImportLibrary;
  this->AddInstallRule(os, destination.c_str(), type, fromFile.c_str(),
                       optional, properties,
                       this->FilePermissions.c_str(), no_dir_permissions,
                       this->Configurations,
                       this->Component.c_str(),
                       no_rename, literal_args.c_str());

  // Fix the install_name settings in installed binaries.
  if(type == cmTarget::SHARED_LIBRARY ||
     type == cmTarget::MODULE_LIBRARY ||
     type == cmTarget::EXECUTABLE)
    {
    this->AddInstallNamePatchRule(os, destination.c_str());
    }
}

//----------------------------------------------------------------------------
void
cmInstallTargetGenerator
::PrepareScriptReference(std::ostream& os, cmTarget* target,
                         const char* place, bool useConfigDir,
                         bool useSOName)
{
  // If the target name may vary with the configuration type then
  // store all possible names ahead of time in variables.
  std::string fname;
  for(std::vector<std::string>::const_iterator i =
        this->ConfigurationTypes->begin();
      i != this->ConfigurationTypes->end(); ++i)
    {
    // Initialize the name.
    fname = "";

    if(useConfigDir)
      {
      // Start with the configuration's subdirectory.
      target->GetMakefile()->GetLocalGenerator()->GetGlobalGenerator()->
        AppendDirectoryForConfig("", i->c_str(), "/", fname);
      }

    // Compute the name of the library.
    std::string targetName;
    std::string targetNameSO;
    std::string targetNameReal;
    std::string targetNameImport;
    target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
                            targetNameImport, i->c_str());
    if(this->ImportLibrary)
      {
      // Use the import library name.
      fname += targetNameImport;
      }
    else if(useSOName)
      {
      // Use the soname.
      fname += targetNameSO;
      }
    else
      {
      // Use the canonical name.
      fname += targetName;
      }

    // Set a variable with the target name for this configuration.
    os << "SET(" << target->GetName() << "_" << place
       << (this->ImportLibrary? "_IMPNAME_" : "_NAME_") << *i
       << " \"" << fname << "\")\n";
    }
}

//----------------------------------------------------------------------------
std::string cmInstallTargetGenerator::GetScriptReference(cmTarget* target,
                                                         const char* place,
                                                         bool useSOName)
{
  if(this->ConfigurationTypes->empty())
    {
    // Reference the target by its one configuration name.
    std::string targetName;
    std::string targetNameSO;
    std::string targetNameReal;
    std::string targetNameImport;
    target->GetLibraryNames(targetName, targetNameSO, targetNameReal,
                            targetNameImport, this->ConfigurationName);
    if(this->ImportLibrary)
      {
      // Use the import library name.
      return targetNameImport;
      }
    else if(useSOName)
      {
      // Use the soname.
      return targetNameSO;
      }
    else
      {
      // Use the canonical name.
      return targetName;
      }
    }
  else
    {
    // Reference the target using the per-configuration variable.
    std::string ref = "${";
    ref += target->GetName();
    if(this->ImportLibrary)
      {
      ref += "_";
      ref += place;
      ref += "_IMPNAME_";
      }
    else
      {
      ref += "_";
      ref += place;
      ref += "_NAME_";
      }
    ref += "${CMAKE_INSTALL_CONFIG_NAME}}";
    return ref;
    }
}

//----------------------------------------------------------------------------
void cmInstallTargetGenerator
::AddInstallNamePatchRule(std::ostream& os,
                                                       const char* destination)
{
  // Build a map of build-tree install_name to install-tree install_name for
  // shared libraries linked to this target.
  std::map<cmStdString, cmStdString> install_name_remap;
  cmTarget::LinkLibraryType linkType = cmTarget::OPTIMIZED;
  const char* config = this->ConfigurationName;
  if(config && cmSystemTools::UpperCase(config) == "DEBUG")
    {
    linkType = cmTarget::DEBUG;
    }
  // TODO: Merge with ComputeLinkInformation.
  const cmTarget::LinkLibraryVectorType& inLibs = 
    this->Target->GetLinkLibraries();
  for(cmTarget::LinkLibraryVectorType::const_iterator j = inLibs.begin();
      j != inLibs.end(); ++j)
    {
    std::string lib = j->first;
    if((this->Target->GetType() == cmTarget::EXECUTABLE ||
        lib != this->Target->GetName()) &&
       (j->second == cmTarget::GENERAL || j->second == linkType))
      {
      if(cmTarget* tgt = this->Target->GetMakefile()->
         GetLocalGenerator()->GetGlobalGenerator()->
         FindTarget(0, lib.c_str()))
        {
        if(tgt->GetType() == cmTarget::SHARED_LIBRARY)
          {
          // If the build tree and install tree use different path
          // components of the install_name field then we need to create a
          // mapping to be applied after installation.
          std::string for_build = tgt->GetInstallNameDirForBuildTree(config);
          std::string for_install = 
            tgt->GetInstallNameDirForInstallTree(config);
          if(for_build != for_install)
            {
            // Map from the build-tree install_name.
            this->PrepareScriptReference(os, tgt, "REMAP_FROM",
                                         !for_build.empty(), true);
            for_build += this->GetScriptReference(tgt, "REMAP_FROM", true);

            // Map to the install-tree install_name.
            this->PrepareScriptReference(os, tgt, "REMAP_TO",
                                         false, true);
            for_install += this->GetScriptReference(tgt, "REMAP_TO", true);

            // Store the mapping entry.
            install_name_remap[for_build] = for_install;
            }
          }
        }
      }
    }

  // Edit the install_name of the target itself if necessary.
  this->PrepareScriptReference(os, this->Target, "REMAPPED", false, true);
  std::string new_id;
  if(this->Target->GetType() == cmTarget::SHARED_LIBRARY)
    {
    std::string for_build = 
      this->Target->GetInstallNameDirForBuildTree(config);
    std::string for_install = 
      this->Target->GetInstallNameDirForInstallTree(config);
    if(for_build != for_install)
      {
      // Prepare to refer to the install-tree install_name.
      new_id = for_install;
      new_id += this->GetScriptReference(this->Target, "REMAPPED", true);
      }
    }

  // Write a rule to run install_name_tool to set the install-tree
  // install_name value and references.
  if(!new_id.empty() || !install_name_remap.empty())
    {
    std::string component_test = "NOT CMAKE_INSTALL_COMPONENT OR "
      "\"${CMAKE_INSTALL_COMPONENT}\" MATCHES \"^(";
    component_test += this->Component;
    component_test += ")$\"";
    os << "IF(" << component_test << ")\n";
    os << "  EXECUTE_PROCESS(COMMAND install_name_tool";
    if(!new_id.empty())
      {
      os << "\n    -id \"" << new_id << "\"";
      }
    for(std::map<cmStdString, cmStdString>::const_iterator
          i = install_name_remap.begin();
        i != install_name_remap.end(); ++i)
      {
      os << "\n    -change \"" << i->first << "\" \"" << i->second << "\"";
      }
    os << "\n    \"$ENV{DESTDIR}" << destination << "/"
       << this->GetScriptReference(this->Target, "REMAPPED", true) << "\")\n";
    os << "ENDIF(" << component_test << ")\n";
    }
}
