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

// Need these for documentation support.
#include "cmake.h"
#include "cmDocumentation.h"
#include "cmCPackGeneratorFactory.h"
#include "cmCPackGenerator.h"
#include "cmake.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"

#include "cmCPackLog.h"

#include <cmsys/CommandLineArguments.hxx>
#include <cmsys/SystemTools.hxx>
#include <cmsys/Encoding.hxx>
#include <locale.h>

//----------------------------------------------------------------------------
static const char * cmDocumentationName[][2] =
{
  {0,
   "  cpack - Packaging driver provided by CMake."},
  {0,0}
};

//----------------------------------------------------------------------------
static const char * cmDocumentationUsage[][2] =
{
  {0,
   "  cpack -G <generator> [options]"},
  {0,0}
};

//----------------------------------------------------------------------------
static const char * cmDocumentationOptions[][2] =
{
    {"-G <generator>", "Use the specified generator to generate package."},
    {"-C <Configuration>", "Specify the project configuration"},
    {"-D <var>=<value>", "Set a CPack variable."},
    {"--config <config file>", "Specify the config file."},
    {"--verbose,-V","enable verbose output"},
    {"--debug","enable debug output (for CPack developers)"},
    {"-P <package name>","override/define CPACK_PACKAGE_NAME"},
    {"-R <package version>","override/define CPACK_PACKAGE_VERSION"},
    {"-B <package directory>","override/define CPACK_PACKAGE_DIRECTORY"},
    {"--vendor <vendor name>","override/define CPACK_PACKAGE_VENDOR"},
    {0,0}
};

//----------------------------------------------------------------------------
int cpackUnknownArgument(const char*, void*)
{
  return 1;
}

//----------------------------------------------------------------------------
struct cpackDefinitions
{
  typedef std::map<std::string, std::string> MapType;
  MapType Map;
  cmCPackLog *Log;
};

//----------------------------------------------------------------------------
int cpackDefinitionArgument(const char* argument, const char* cValue,
  void* call_data)
{
  (void)argument;
  cpackDefinitions* def = static_cast<cpackDefinitions*>(call_data);
  std::string value = cValue;
  size_t pos = value.find_first_of("=");
  if ( pos == std::string::npos )
    {
    cmCPack_Log(def->Log, cmCPackLog::LOG_ERROR,
      "Please specify CPack definitions as: KEY=VALUE" << std::endl);
    return 0;
    }
  std::string key = value.substr(0, pos);
  value = value.c_str() + pos + 1;
  def->Map[key] = value;
  cmCPack_Log(def->Log, cmCPackLog::LOG_DEBUG, "Set CPack variable: "
    << key << " to \"" << value << "\"" << std::endl);
  return 1;
}


//----------------------------------------------------------------------------
// this is CPack.
int main (int argc, char const* const* argv)
{
  setlocale(LC_CTYPE, "");
  cmsys::Encoding::CommandLineArguments args =
    cmsys::Encoding::CommandLineArguments::Main(argc, argv);
  argc = args.argc();
  argv = args.argv();

  cmSystemTools::FindCMakeResources(argv[0]);
  cmCPackLog log;

  log.SetErrorPrefix("CPack Error: ");
  log.SetWarningPrefix("CPack Warning: ");
  log.SetOutputPrefix("CPack: ");
  log.SetVerbosePrefix("CPack Verbose: ");

  cmSystemTools::EnableMSVCDebugHook();

  if ( cmSystemTools::GetCurrentWorkingDirectory().size() == 0 )
    {
    cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
      "Current working directory cannot be established." << std::endl);
    return 1;
    }

  std::string generator;
  bool help = false;
  bool helpVersion = false;
  bool verbose = false;
  bool debug = false;
  std::string helpFull;
  std::string helpMAN;
  std::string helpHTML;

  std::string cpackProjectName;
  std::string cpackProjectDirectory;
  std::string cpackBuildConfig;
  std::string cpackProjectVersion;
  std::string cpackProjectPatch;
  std::string cpackProjectVendor;
  std::string cpackConfigFile;

  cpackDefinitions definitions;
  definitions.Log = &log;

  cpackConfigFile = "";

  cmsys::CommandLineArguments arg;
  arg.Initialize(argc, argv);
  typedef cmsys::CommandLineArguments argT;
  // Help arguments
  arg.AddArgument("--help", argT::NO_ARGUMENT, &help, "CPack help");
  arg.AddArgument("--help-full", argT::SPACE_ARGUMENT, &helpFull,
    "CPack help");
  arg.AddArgument("--help-html", argT::SPACE_ARGUMENT, &helpHTML,
    "CPack help");
  arg.AddArgument("--help-man", argT::SPACE_ARGUMENT, &helpMAN, "CPack help");
  arg.AddArgument("--version", argT::NO_ARGUMENT, &helpVersion, "CPack help");

  arg.AddArgument("-V", argT::NO_ARGUMENT, &verbose, "CPack verbose");
  arg.AddArgument("--verbose", argT::NO_ARGUMENT, &verbose, "-V");
  arg.AddArgument("--debug", argT::NO_ARGUMENT, &debug, "-V");
  arg.AddArgument("--config", argT::SPACE_ARGUMENT, &cpackConfigFile,
    "CPack configuration file");
  arg.AddArgument("-C", argT::SPACE_ARGUMENT, &cpackBuildConfig,
    "CPack build configuration");
  arg.AddArgument("-G", argT::SPACE_ARGUMENT,
    &generator, "CPack generator");
  arg.AddArgument("-P", argT::SPACE_ARGUMENT,
    &cpackProjectName, "CPack project name");
  arg.AddArgument("-R", argT::SPACE_ARGUMENT,
    &cpackProjectVersion, "CPack project version");
  arg.AddArgument("-B", argT::SPACE_ARGUMENT,
    &cpackProjectDirectory, "CPack project directory");
  arg.AddArgument("--patch", argT::SPACE_ARGUMENT,
    &cpackProjectPatch, "CPack project patch");
  arg.AddArgument("--vendor", argT::SPACE_ARGUMENT,
    &cpackProjectVendor, "CPack project vendor");
  arg.AddCallback("-D", argT::SPACE_ARGUMENT,
    cpackDefinitionArgument, &definitions, "CPack Definitions");
  arg.SetUnknownArgumentCallback(cpackUnknownArgument);

  // Parse command line
  int parsed = arg.Parse();

  // Setup logging
  if ( verbose )
    {
    log.SetVerbose(verbose);
    cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Verbose" << std::endl);
    }
  if ( debug )
    {
    log.SetDebug(debug);
    cmCPack_Log(&log, cmCPackLog::LOG_OUTPUT, "Enable Debug" << std::endl);
    }

  cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
    "Read CPack config file: " << cpackConfigFile << std::endl);

  cmake cminst;
  cminst.RemoveUnscriptableCommands();
  cmGlobalGenerator cmgg;
  cmgg.SetCMakeInstance(&cminst);
  cmsys::auto_ptr<cmLocalGenerator> cmlg(cmgg.CreateLocalGenerator());
  cmMakefile* globalMF = cmlg->GetMakefile();

  bool cpackConfigFileSpecified = true;
  if ( cpackConfigFile.empty() )
    {
    cpackConfigFile = cmSystemTools::GetCurrentWorkingDirectory();
    cpackConfigFile += "/CPackConfig.cmake";
    cpackConfigFileSpecified = false;
    }

  cmCPackGeneratorFactory generators;
  generators.SetLogger(&log);
  cmCPackGenerator* cpackGenerator = 0;

  cmDocumentation doc;
  doc.addCPackStandardDocSections();
  /* Were we invoked to display doc or to do some work ?
   * Unlike cmake launching cpack with zero argument
   * should launch cpack using "cpackConfigFile" if it exists
   * in the current directory.
   */
  if((doc.CheckOptions(argc, argv,"-G")) && !(argc==1))
    {
      help = true;
    }
  else
    {
      help = false;
    }

  // This part is used for cpack documentation lookup as well.
  cminst.AddCMakePaths();

  if ( parsed && !help )
    {
    // find out which system cpack is running on, so it can setup the search
    // paths, so FIND_XXX() commands can be used in scripts
    std::string systemFile =
      globalMF->GetModulesFile("CMakeDetermineSystem.cmake");
    if (!globalMF->ReadListFile(0, systemFile.c_str()))
      {
      cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
        "Error reading CMakeDetermineSystem.cmake" << std::endl);
      return 1;
      }

    systemFile =
      globalMF->GetModulesFile("CMakeSystemSpecificInformation.cmake");
    if (!globalMF->ReadListFile(0, systemFile.c_str()))
      {
      cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
        "Error reading CMakeSystemSpecificInformation.cmake" << std::endl);
      return 1;
      }

    if ( !cpackBuildConfig.empty() )
      {
      globalMF->AddDefinition("CPACK_BUILD_CONFIG", cpackBuildConfig.c_str());
      }

    if ( cmSystemTools::FileExists(cpackConfigFile.c_str()) )
      {
      cpackConfigFile =
        cmSystemTools::CollapseFullPath(cpackConfigFile.c_str());
      cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
        "Read CPack configuration file: " << cpackConfigFile
        << std::endl);
      if ( !globalMF->ReadListFile(0, cpackConfigFile.c_str()) )
        {
        cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
          "Problem reading CPack config file: \""
          << cpackConfigFile << "\"" << std::endl);
        return 1;
        }
      }
    else if ( cpackConfigFileSpecified )
      {
      cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
        "Cannot find CPack config file: \"" <<
         cpackConfigFile << "\"" << std::endl);
      return 1;
      }

    if ( !generator.empty() )
      {
      globalMF->AddDefinition("CPACK_GENERATOR", generator.c_str());
      }
    if ( !cpackProjectName.empty() )
      {
      globalMF->AddDefinition("CPACK_PACKAGE_NAME", cpackProjectName.c_str());
      }
    if ( !cpackProjectVersion.empty() )
      {
      globalMF->AddDefinition("CPACK_PACKAGE_VERSION",
        cpackProjectVersion.c_str());
      }
    if ( !cpackProjectVendor.empty() )
      {
      globalMF->AddDefinition("CPACK_PACKAGE_VENDOR",
        cpackProjectVendor.c_str());
      }
    // if this is not empty it has been set on the command line
    // go for it. Command line override values set in config file.
    if ( !cpackProjectDirectory.empty() )
      {
      globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY",
                              cpackProjectDirectory.c_str());
      }
    // The value has not been set on the command line
    else
      {
      // get a default value (current working directory)
      cpackProjectDirectory = cmsys::SystemTools::GetCurrentWorkingDirectory();
      // use default value iff no value has been provided by the config file
      if (!globalMF->IsSet("CPACK_PACKAGE_DIRECTORY"))
        {
        globalMF->AddDefinition("CPACK_PACKAGE_DIRECTORY",
                                cpackProjectDirectory.c_str());
        }
      }
    cpackDefinitions::MapType::iterator cdit;
    for ( cdit = definitions.Map.begin();
      cdit != definitions.Map.end();
      ++cdit )
      {
      globalMF->AddDefinition(cdit->first, cdit->second.c_str());
      }

    const char* cpackModulesPath =
      globalMF->GetDefinition("CPACK_MODULE_PATH");
    if ( cpackModulesPath )
      {
      globalMF->AddDefinition("CMAKE_MODULE_PATH", cpackModulesPath);
      }
    const char* genList = globalMF->GetDefinition("CPACK_GENERATOR");
    if ( !genList )
      {
      cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
        "CPack generator not specified" << std::endl);
      }
    else
      {
      std::vector<std::string> generatorsVector;
      cmSystemTools::ExpandListArgument(genList,
        generatorsVector);
      std::vector<std::string>::iterator it;
      for ( it = generatorsVector.begin();
        it != generatorsVector.end();
        ++it )
        {
        const char* gen = it->c_str();
        cmMakefile newMF(*globalMF);
        cmMakefile* mf = &newMF;
        cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE,
          "Specified generator: " << gen << std::endl);
        if ( parsed && !mf->GetDefinition("CPACK_PACKAGE_NAME") )
          {
          cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
            "CPack project name not specified" << std::endl);
          parsed = 0;
          }
        if (parsed &&
            !(mf->GetDefinition("CPACK_PACKAGE_VERSION") ||
              (mf->GetDefinition("CPACK_PACKAGE_VERSION_MAJOR") &&
               mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR") &&
               mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH"))))
          {
          cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
            "CPack project version not specified" << std::endl
            << "Specify CPACK_PACKAGE_VERSION, or "
            "CPACK_PACKAGE_VERSION_MAJOR, "
            "CPACK_PACKAGE_VERSION_MINOR, and CPACK_PACKAGE_VERSION_PATCH."
            << std::endl);
          parsed = 0;
          }
        if ( parsed )
          {
          cpackGenerator = generators.NewGenerator(gen);
          if ( !cpackGenerator )
            {
            cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
              "Cannot initialize CPack generator: "
              << gen << std::endl);
            parsed = 0;
            }
          if ( parsed && !cpackGenerator->Initialize(gen, mf) )
            {
            cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
              "Cannot initialize the generator " << gen << std::endl);
            parsed = 0;
            }

          if ( !mf->GetDefinition("CPACK_INSTALL_COMMANDS") &&
            !mf->GetDefinition("CPACK_INSTALLED_DIRECTORIES") &&
            !mf->GetDefinition("CPACK_INSTALL_CMAKE_PROJECTS") )
            {
            cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
              "Please specify build tree of the project that uses CMake "
              "using CPACK_INSTALL_CMAKE_PROJECTS, specify "
              "CPACK_INSTALL_COMMANDS, or specify "
              "CPACK_INSTALLED_DIRECTORIES."
              << std::endl);
            parsed = 0;
            }
          if ( parsed )
            {
            const char* projName = mf->GetDefinition("CPACK_PACKAGE_NAME");
            cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "Use generator: "
              << cpackGenerator->GetNameOfClass() << std::endl);
            cmCPack_Log(&log, cmCPackLog::LOG_VERBOSE, "For project: "
              << projName << std::endl);

            const char* projVersion =
              mf->GetDefinition("CPACK_PACKAGE_VERSION");
            if ( !projVersion )
              {
              const char* projVersionMajor
                = mf->GetDefinition("CPACK_PACKAGE_VERSION_MAJOR");
              const char* projVersionMinor
                = mf->GetDefinition("CPACK_PACKAGE_VERSION_MINOR");
              const char* projVersionPatch
                = mf->GetDefinition("CPACK_PACKAGE_VERSION_PATCH");
              cmOStringStream ostr;
              ostr << projVersionMajor << "." << projVersionMinor << "."
                << projVersionPatch;
              mf->AddDefinition("CPACK_PACKAGE_VERSION",
                                ostr.str().c_str());
              }

            int res = cpackGenerator->DoPackage();
            if ( !res )
              {
              cmCPack_Log(&log, cmCPackLog::LOG_ERROR,
                "Error when generating package: " << projName << std::endl);
              return 1;
              }
            }
          }
        }
      }
    }

  /* In this case we are building the documentation object
   * instance in order to create appropriate structure
   * in order to satisfy the appropriate --help-xxx request
   */
  if ( help )
    {
    // Construct and print requested documentation.

    doc.SetName("cpack");
    doc.SetSection("Name",cmDocumentationName);
    doc.SetSection("Usage",cmDocumentationUsage);
    doc.PrependSection("Options",cmDocumentationOptions);

    std::vector<cmDocumentationEntry> v;
    cmCPackGeneratorFactory::DescriptionsMap::const_iterator generatorIt;
    for( generatorIt = generators.GetGeneratorsList().begin();
      generatorIt != generators.GetGeneratorsList().end();
      ++ generatorIt )
      {
      cmDocumentationEntry e;
      e.Name = generatorIt->first.c_str();
      e.Brief = generatorIt->second.c_str();
      v.push_back(e);
      }
    doc.SetSection("Generators",v);

#undef cout
    return doc.PrintRequestedDocumentation(std::cout)? 0:1;
#define cout no_cout_use_cmCPack_Log
    }

  if (cmSystemTools::GetErrorOccuredFlag())
    {
    return 1;
    }

  return 0;
}
