/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2004-2009 Kitware, Inc.
  Copyright 2004 Alexander Neundorf (neundorf@kde.org)
  Copyright 2013 Eran Ifrah (eran.ifrah@gmail.com)

  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 "cmExtraCodeLiteGenerator.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmake.h"
#include "cmSourceFile.h"
#include "cmGeneratedFileStream.h"
#include "cmSystemTools.h"

#include <cmsys/SystemTools.hxx>
#include <cmsys/SystemInformation.hxx>
#include <cmsys/Directory.hxx>
#include "cmStandardIncludes.h"
#include "cmXMLSafe.h"

//----------------------------------------------------------------------------
void cmExtraCodeLiteGenerator::GetDocumentation(cmDocumentationEntry& entry,
                                                const std::string&) const
{
  entry.Name = this->GetName();
  entry.Brief = "Generates CodeLite project files.";
}

cmExtraCodeLiteGenerator::cmExtraCodeLiteGenerator()
  : cmExternalMakefileProjectGenerator()
  , ConfigName("NoConfig")
  , CpuCount(2)
{
#if defined(_WIN32)
  this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
  this->SupportedGlobalGenerators.push_back("NMake Makefiles");
#endif
  this->SupportedGlobalGenerators.push_back("Ninja");
  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
}

void cmExtraCodeLiteGenerator::Generate()
{
  // Hold root tree information for creating the workspace
  std::string workspaceProjectName;
  std::string workspaceOutputDir;
  std::string workspaceFileName;
  std::string workspaceSourcePath;
  std::string lprjdebug;

  cmGeneratedFileStream fout;

  // loop projects and locate the root project.
  // and extract the information for creating the worspace
  for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
       it = this->GlobalGenerator->GetProjectMap().begin();
       it!= this->GlobalGenerator->GetProjectMap().end();
       ++it)
    {
    const cmMakefile* mf =it->second[0]->GetMakefile();
    this->ConfigName = GetConfigurationName( mf );

    if (strcmp(it->second[0]->GetCurrentBinaryDirectory(),
               it->second[0]->GetBinaryDirectory()) == 0)
      {
      workspaceOutputDir   = it->second[0]->GetCurrentBinaryDirectory();
      workspaceProjectName = it->second[0]->GetProjectName();
      workspaceSourcePath  = it->second[0]->GetSourceDirectory();
      workspaceFileName    = workspaceOutputDir+"/";
      workspaceFileName   += workspaceProjectName + ".workspace";
      this->WorkspacePath = it->second[0]->GetCurrentBinaryDirectory();;

      fout.Open(workspaceFileName.c_str(), false, false);
      fout << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
           "<CodeLite_Workspace Name=\"" << workspaceProjectName << "\" >\n";
      }
    }

  // for each sub project in the workspace create a codelite project
  for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
       it = this->GlobalGenerator->GetProjectMap().begin();
       it!= this->GlobalGenerator->GetProjectMap().end();
       ++it)
    {
    // retrive project information
    std::string outputDir   = it->second[0]->GetCurrentBinaryDirectory();
    std::string projectName = it->second[0]->GetProjectName();
    std::string filename    = outputDir + "/" + projectName + ".project";

    // Make the project file relative to the workspace
    filename = cmSystemTools::RelativePath(this->WorkspacePath.c_str(),
                                          filename.c_str());

    // create a project file
    this->CreateProjectFile(it->second);
    fout << "  <Project Name=\"" << projectName << "\" Path=\""
    << filename << "\" Active=\"No\"/>\n";
    lprjdebug += "<Project Name=\"" + projectName
              + "\" ConfigName=\"" + this->ConfigName + "\"/>\n";
    }

  fout << "  <BuildMatrix>\n"
       "    <WorkspaceConfiguration Name=\""
       << this->ConfigName << "\" Selected=\"yes\">\n"
       "      " << lprjdebug << ""
       "    </WorkspaceConfiguration>\n"
       "  </BuildMatrix>\n"
       "</CodeLite_Workspace>\n";
}

/* create the project file */
void cmExtraCodeLiteGenerator::CreateProjectFile(
  const std::vector<cmLocalGenerator*>& lgs)
{
  std::string outputDir   = lgs[0]->GetCurrentBinaryDirectory();
  std::string projectName = lgs[0]->GetProjectName();
  std::string filename    = outputDir + "/";

  filename += projectName + ".project";
  this->CreateNewProjectFile(lgs, filename);
}

void cmExtraCodeLiteGenerator
::CreateNewProjectFile(const std::vector<cmLocalGenerator*>& lgs,
                       const std::string& filename)
{
  const cmMakefile* mf=lgs[0]->GetMakefile();
  cmGeneratedFileStream fout(filename.c_str());
  if(!fout)
    {
    return;
    }

  ////////////////////////////////////
  fout << "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
       "<CodeLite_Project Name=\"" << lgs[0]->GetProjectName()
       << "\" InternalType=\"\">\n";

  // Collect all used source files in the project
  // Sort them into two containers, one for C/C++ implementation files
  // which may have an acompanying header, one for all other files
  std::string projectType;

  std::vector<std::string> srcExts =
      this->GlobalGenerator->GetCMakeInstance()->GetSourceExtensions();
  std::vector<std::string> headerExts =
      this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();

  std::map<std::string, cmSourceFile*> cFiles;
  std::set<std::string> otherFiles;
  for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
       lg!=lgs.end(); lg++)
    {
    cmMakefile* makefile=(*lg)->GetMakefile();
    std::vector<cmGeneratorTarget*> targets=(*lg)->GetGeneratorTargets();
    for (std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
         ti != targets.end(); ti++)
      {

      switch((*ti)->GetType())
        {
        case cmState::EXECUTABLE:
          {
          projectType = "Executable";
          }
        break;
        case cmState::STATIC_LIBRARY:
          {
          projectType = "Static Library";
          }
        break;
        case cmState::SHARED_LIBRARY:
          {
          projectType = "Dynamic Library";
          }
        break;
        case cmState::MODULE_LIBRARY:
          {
          projectType = "Dynamic Library";
          }
        break;
        default:  // intended fallthrough
          break;
        }

      switch((*ti)->GetType())
        {
        case cmState::EXECUTABLE:
        case cmState::STATIC_LIBRARY:
        case cmState::SHARED_LIBRARY:
        case cmState::MODULE_LIBRARY:
          {
          std::vector<cmSourceFile*> sources;
          cmGeneratorTarget* gt = *ti;
          gt->GetSourceFiles(sources,
                            makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
          for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
               si!=sources.end(); si++)
            {
            // check whether it is a C/C++ implementation file
            bool isCFile = false;
            std::string lang = (*si)->GetLanguage();
            if (lang == "C" || lang == "CXX")
              {
              std::string srcext = (*si)->GetExtension();
              for(std::vector<std::string>::const_iterator
                  ext = srcExts.begin(); ext != srcExts.end(); ++ext)
                {
                if (srcext == *ext)
                  {
                  isCFile = true;
                  break;
                  }
                }
              }

            // then put it accordingly into one of the two containers
            if (isCFile)
              {
              cFiles[(*si)->GetFullPath()] = *si ;
              }
            else
              {
              otherFiles.insert((*si)->GetFullPath());
              }
            }
          }
        default:  // intended fallthrough
          break;
        }
      }
    }

  // The following loop tries to add header files matching to implementation
  // files to the project. It does that by iterating over all source files,
  // replacing the file name extension with ".h" and checks whether such a
  // file exists. If it does, it is inserted into the map of files.
  // A very similar version of that code exists also in the kdevelop
  // project generator.
  for (std::map<std::string, cmSourceFile*>::const_iterator
       sit=cFiles.begin();
       sit!=cFiles.end();
       ++sit)
    {
    std::string headerBasename=cmSystemTools::GetFilenamePath(sit->first);
    headerBasename+="/";
    headerBasename+=cmSystemTools::GetFilenameWithoutExtension(sit->first);

    // check if there's a matching header around
    for(std::vector<std::string>::const_iterator
        ext = headerExts.begin();
        ext != headerExts.end();
        ++ext)
      {
      std::string hname=headerBasename;
      hname += ".";
      hname += *ext;
      // if it's already in the set, don't check if it exists on disk
      std::set<std::string>::const_iterator headerIt=otherFiles.find(hname);
      if (headerIt != otherFiles.end())
        {
        break;
        }

      if(cmSystemTools::FileExists(hname.c_str()))
        {
        otherFiles.insert(hname);
        break;
        }
      }
    }

  // Get the project path ( we need it later to convert files to
  // their relative path)
  std::string projectPath = cmSystemTools::GetFilenamePath(filename);

  // Create 2 virtual folders: src and include
  // and place all the implementation files into the src
  // folder, the rest goes to the include folder
  fout<< "  <VirtualDirectory Name=\"src\">\n";

  // insert all source files in the codelite project
  // first the C/C++ implementation files, then all others
  for (std::map<std::string, cmSourceFile*>::const_iterator
       sit=cFiles.begin();
       sit!=cFiles.end();
       ++sit)
    {
    std::string relativePath =
      cmSystemTools::RelativePath(projectPath.c_str(), sit->first.c_str());
    fout<< "    <File Name=\"" << relativePath << "\"/>\n";
    }
  fout<< "  </VirtualDirectory>\n";
  fout<< "  <VirtualDirectory Name=\"include\">\n";
  for (std::set<std::string>::const_iterator
       sit=otherFiles.begin();
       sit!=otherFiles.end();
       ++sit)
    {
    std::string relativePath =
      cmSystemTools::RelativePath(projectPath.c_str(), sit->c_str());
    fout << "    <File Name=\"" << relativePath << "\"/>\n";
    }
  fout << "  </VirtualDirectory>\n";

  // Get the number of CPUs. We use this information for the make -jN
  // command
  cmsys::SystemInformation info;
  info.RunCPUCheck();

  this->CpuCount = info.GetNumberOfLogicalCPU() *
                   info.GetNumberOfPhysicalCPU();

  std::string cleanCommand      = GetCleanCommand(mf);
  std::string buildCommand      = GetBuildCommand(mf);
  std::string rebuildCommand    = GetRebuildCommand(mf);
  std::string singleFileCommand = GetSingleFileBuildCommand(mf);

  std::string codeliteCompilerName = this->GetCodeLiteCompilerName(mf);

  fout << "\n"
     "  <Settings Type=\"" << projectType << "\">\n"
     "    <Configuration Name=\"" << this->ConfigName << "\" CompilerType=\""
     << codeliteCompilerName << "\" DebuggerType=\"GNU gdb debugger\" "
     "Type=\""
     << projectType << "\" BuildCmpWithGlobalSettings=\"append\" "
     "BuildLnkWithGlobalSettings=\"append\" "
     "BuildResWithGlobalSettings=\"append\">\n"
     "      <Compiler Options=\"-g\" "
     "Required=\"yes\" PreCompiledHeader=\"\">\n"
     "        <IncludePath Value=\".\"/>\n"
     "      </Compiler>\n"
     "      <Linker Options=\"\" Required=\"yes\"/>\n"
     "      <ResourceCompiler Options=\"\" Required=\"no\"/>\n"
     "      <General OutputFile=\"$(IntermediateDirectory)/$(ProjectName)\" "
     "IntermediateDirectory=\"./\" Command=\"./$(ProjectName)\" "
     "CommandArguments=\"\" WorkingDirectory=\"$(IntermediateDirectory)\" "
     "PauseExecWhenProcTerminates=\"yes\"/>\n"
     "      <Debugger IsRemote=\"no\" RemoteHostName=\"\" "
     "RemoteHostPort=\"\" DebuggerPath=\"\">\n"
     "        <PostConnectCommands/>\n"
     "        <StartupCommands/>\n"
     "      </Debugger>\n"
     "      <PreBuild/>\n"
     "      <PostBuild/>\n"
     "      <CustomBuild Enabled=\"yes\">\n"
     "        <RebuildCommand>" << rebuildCommand << "</RebuildCommand>\n"
     "        <CleanCommand>" << cleanCommand << "</CleanCommand>\n"
     "        <BuildCommand>" << buildCommand << "</BuildCommand>\n"
     "        <SingleFileCommand>" << singleFileCommand
     << "</SingleFileCommand>\n"
     "        <PreprocessFileCommand/>\n"
     "        <WorkingDirectory>$(WorkspacePath)</WorkingDirectory>\n"
     "      </CustomBuild>\n"
     "      <AdditionalRules>\n"
     "        <CustomPostBuild/>\n"
     "        <CustomPreBuild/>\n"
     "      </AdditionalRules>\n"
     "    </Configuration>\n"
     "    <GlobalSettings>\n"
     "      <Compiler Options=\"\">\n"
     "        <IncludePath Value=\".\"/>\n"
     "      </Compiler>\n"
     "      <Linker Options=\"\">\n"
     "        <LibraryPath Value=\".\"/>\n"
     "      </Linker>\n"
     "      <ResourceCompiler Options=\"\"/>\n"
     "    </GlobalSettings>\n"
     "  </Settings>\n"
     "</CodeLite_Project>\n";
}

std::string
cmExtraCodeLiteGenerator::GetCodeLiteCompilerName(const cmMakefile* mf) const
{
  // figure out which language to use
  // for now care only for C and C++
  std::string compilerIdVar = "CMAKE_CXX_COMPILER_ID";
  if (this->GlobalGenerator->GetLanguageEnabled("CXX") == false)
    {
    compilerIdVar = "CMAKE_C_COMPILER_ID";
    }

  std::string compilerId = mf->GetSafeDefinition(compilerIdVar);
  std::string compiler = "gnu g++"; // default to g++

  // Since we need the compiler for parsing purposes only
  // it does not matter if we use clang or clang++, same as
  // "gnu gcc" vs "gnu g++"
  if (compilerId == "MSVC")
    {
    compiler = "VC++";
    }
  else if (compilerId == "Clang")
    {
    compiler = "clang++";
    }
  else if (compilerId == "GNU")
    {
    compiler = "gnu g++";
    }
  return compiler;
}

std::string
cmExtraCodeLiteGenerator::GetConfigurationName(const cmMakefile* mf) const
{
  std::string confName = mf->GetSafeDefinition("CMAKE_BUILD_TYPE");
  // Trim the configuration name from whitespaces (left and right)
  confName.erase(0, confName.find_first_not_of(" \t\r\v\n"));
  confName.erase(confName.find_last_not_of(" \t\r\v\n")+1);
  if ( confName.empty() )
    {
    confName = "NoConfig";
    }
  return confName;
}

std::string
cmExtraCodeLiteGenerator::GetBuildCommand(const cmMakefile* mf) const
{
  std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR");
  std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  std::string buildCommand = make; // Default
  if ( generator == "NMake Makefiles" ||
       generator == "Ninja" )
    {
    buildCommand = make;
    }
  else if ( generator == "MinGW Makefiles" ||
            generator == "Unix Makefiles" )
    {
    std::ostringstream ss;
    ss << make << " -j " << this->CpuCount;
    buildCommand = ss.str();
    }
  return buildCommand;
}

std::string
cmExtraCodeLiteGenerator::GetCleanCommand(const cmMakefile* mf) const
{
  return GetBuildCommand(mf) + " clean";
}

std::string
cmExtraCodeLiteGenerator::GetRebuildCommand(const cmMakefile* mf) const
{
  return GetCleanCommand(mf) + cmXMLSafe(" && ").str() + GetBuildCommand(mf);
}

std::string
cmExtraCodeLiteGenerator::GetSingleFileBuildCommand
(const cmMakefile* mf) const
{
  std::string buildCommand;
  std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  std::string generator = mf->GetSafeDefinition("CMAKE_GENERATOR");
  if ( generator == "Unix Makefiles" || generator == "MinGW Makefiles" )
    {
    std::ostringstream ss;
    ss << make << " -f$(ProjectPath)/Makefile $(CurrentFileName).cpp.o";
    buildCommand = ss.str();
    }
  return buildCommand;
}
