/*============================================================================
  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 "cmExportLibraryDependenciesCommand.h"
#include "cmGlobalGenerator.h"
#include "cmGeneratedFileStream.h"
#include "cmake.h"
#include "cmVersion.h"

#include <cmsys/auto_ptr.hxx>

bool cmExportLibraryDependenciesCommand
::InitialPass(std::vector<std::string> const& args, cmExecutionStatus &)
{
  if(this->Disallowed(cmPolicies::CMP0033,
      "The export_library_dependencies command should not be called; "
      "see CMP0033."))
    { return true; }
  if(args.size() < 1 )
    {
    this->SetError("called with incorrect number of arguments");
    return false;
    }

  // store the arguments for the final pass
  this->Filename = args[0];
  this->Append = false;
  if(args.size() > 1)
    {
    if(args[1] == "APPEND")
      {
      this->Append = true;
      }
    }
  return true;
}


void cmExportLibraryDependenciesCommand::FinalPass()
{
  // export_library_dependencies() shouldn't modify anything
  // ensure this by calling a const method
  this->ConstFinalPass();
}

void cmExportLibraryDependenciesCommand::ConstFinalPass() const
{
  // Use copy-if-different if not appending.
  cmsys::auto_ptr<cmsys::ofstream> foutPtr;
  if(this->Append)
    {
    cmsys::auto_ptr<cmsys::ofstream> ap(
      new cmsys::ofstream(this->Filename.c_str(), std::ios::app));
    foutPtr = ap;
    }
  else
    {
    cmsys::auto_ptr<cmGeneratedFileStream> ap(
      new cmGeneratedFileStream(this->Filename.c_str(), true));
    ap->SetCopyIfDifferent(true);
    foutPtr = ap;
    }
  std::ostream& fout = *foutPtr.get();

  if (!fout)
    {
    cmSystemTools::Error("Error Writing ", this->Filename.c_str());
    cmSystemTools::ReportLastSystemError("");
    return;
    }

  // Collect dependency information about all library targets built in
  // the project.
  cmake* cm = this->Makefile->GetCMakeInstance();
  cmGlobalGenerator* global = cm->GetGlobalGenerator();
  const std::vector<cmMakefile*>& locals = global->GetMakefiles();
  std::map<std::string, std::string> libDepsOld;
  std::map<std::string, std::string> libDepsNew;
  std::map<std::string, std::string> libTypes;
  for(std::vector<cmMakefile*>::const_iterator i = locals.begin();
      i != locals.end(); ++i)
    {
    const cmTargets &tgts = (*i)->GetTargets();
    for(cmTargets::const_iterator l = tgts.begin();
        l != tgts.end(); ++l)
      {
      // Get the current target.
      cmTarget const& target = l->second;

      // Skip non-library targets.
      if(target.GetType() < cmState::STATIC_LIBRARY
         || target.GetType() > cmState::MODULE_LIBRARY)
        {
        continue;
        }

      // Construct the dependency variable name.
      std::string targetEntry = target.GetName();
      targetEntry += "_LIB_DEPENDS";

      // Construct the dependency variable value with the direct link
      // dependencies.
      std::string valueOld;
      std::string valueNew;
      cmTarget::LinkLibraryVectorType const& libs =
        target.GetOriginalLinkLibraries();
      for(cmTarget::LinkLibraryVectorType::const_iterator li = libs.begin();
          li != libs.end(); ++li)
        {
        std::string ltVar = li->first;
        ltVar += "_LINK_TYPE";
        std::string ltValue;
        switch(li->second)
          {
          case GENERAL_LibraryType:
            valueNew += "general;";
            ltValue = "general";
            break;
          case DEBUG_LibraryType:
            valueNew += "debug;";
            ltValue = "debug";
            break;
          case OPTIMIZED_LibraryType:
            valueNew += "optimized;";
            ltValue = "optimized";
            break;
          }
        std::string lib = li->first;
        if(cmTarget* libtgt = global->FindTarget(lib))
          {
          // Handle simple output name changes.  This command is
          // deprecated so we do not support full target name
          // translation (which requires per-configuration info).
          if(const char* outname = libtgt->GetProperty("OUTPUT_NAME"))
            {
            lib = outname;
            }
          }
        valueOld += lib;
        valueOld += ";";
        valueNew += lib;
        valueNew += ";";

        std::string& ltEntry = libTypes[ltVar];
        if(ltEntry.empty())
          {
          ltEntry = ltValue;
          }
        else if(ltEntry != ltValue)
          {
          ltEntry = "general";
          }
        }
      libDepsNew[targetEntry] = valueNew;
      libDepsOld[targetEntry] = valueOld;
      }
    }

  // Generate dependency information for both old and new style CMake
  // versions.
  const char* vertest =
    "\"${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}\" GREATER 2.4";
  fout << "# Generated by CMake " <<  cmVersion::GetCMakeVersion() << "\n\n";
  fout << "if(" << vertest << ")\n";
  fout << "  # Information for CMake 2.6 and above.\n";
  for(std::map<std::string, std::string>::const_iterator
        i = libDepsNew.begin();
      i != libDepsNew.end(); ++i)
    {
    if(!i->second.empty())
      {
      fout << "  set(\"" << i->first << "\" \"" << i->second << "\")\n";
      }
    }
  fout << "else()\n";
  fout << "  # Information for CMake 2.4 and lower.\n";
  for(std::map<std::string, std::string>::const_iterator
        i = libDepsOld.begin();
      i != libDepsOld.end(); ++i)
    {
    if(!i->second.empty())
      {
      fout << "  set(\"" << i->first << "\" \"" << i->second << "\")\n";
      }
    }
  for(std::map<std::string, std::string>::const_iterator i = libTypes.begin();
      i != libTypes.end(); ++i)
    {
    if(i->second != "general")
      {
      fout << "  set(\"" << i->first << "\" \"" << i->second << "\")\n";
      }
    }
  fout << "endif()\n";
  return;
}
