/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2004-2009 Kitware, Inc.
  Copyright 2004 Alexander Neundorf (neundorf@kde.org)

  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 "cmGlobalKdevelopGenerator.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/Directory.hxx>

//----------------------------------------------------------------------------
void cmGlobalKdevelopGenerator
::GetDocumentation(cmDocumentationEntry& entry, const char*) const
{
  entry.Name = this->GetName();
  entry.Brief = "Generates KDevelop 3 project files.";
  entry.Full =
    "Project files for KDevelop 3 will be created in the top directory "
    "and in every subdirectory which features a CMakeLists.txt file "
    "containing a PROJECT() call. "
    "If you change the settings using KDevelop cmake will try its best "
    "to keep your changes when regenerating the project files. "
    "Additionally a hierarchy of UNIX makefiles is generated into the "
    "build tree.  Any "
    "standard UNIX-style make program can build the project through the "
    "default make target.  A \"make install\" target is also provided.";
}

cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
:cmExternalMakefileProjectGenerator()
{
  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
#ifdef CMAKE_USE_NINJA
  this->SupportedGlobalGenerators.push_back("Ninja");
#endif
}

void cmGlobalKdevelopGenerator::Generate()
{
  // for each sub project in the project create
  // a kdevelop project
  for (std::map<cmStdString, std::vector<cmLocalGenerator*> >::const_iterator
       it = this->GlobalGenerator->GetProjectMap().begin();
      it!= this->GlobalGenerator->GetProjectMap().end();
      ++it)
    {
    cmMakefile* mf = it->second[0]->GetMakefile();
    std::string outputDir=mf->GetStartOutputDirectory();
    std::string projectDir=mf->GetHomeDirectory();
    std::string projectName=mf->GetProjectName();
    std::string cmakeFilePattern("CMakeLists.txt;*.cmake;");
    std::string fileToOpen;
    const std::vector<cmLocalGenerator*>& lgs= it->second;
    // create the project.kdevelop.filelist file
    if(!this->CreateFilelistFile(lgs, outputDir, projectDir,
                                 projectName, cmakeFilePattern, fileToOpen))
      {
      cmSystemTools::Error("Can not create filelist file");
      return;
      }
    //try to find the name of an executable so we have something to
    //run from kdevelop for now just pick the first executable found
    std::string executable;
    for (std::vector<cmLocalGenerator*>::const_iterator lg=lgs.begin();
         lg!=lgs.end(); lg++)
      {
      cmMakefile* makefile=(*lg)->GetMakefile();
      cmTargets& targets=makefile->GetTargets();
      for (cmTargets::iterator ti = targets.begin();
           ti != targets.end(); ti++)
        {
        if (ti->second.GetType()==cmTarget::EXECUTABLE)
          {
          executable = ti->second.GetProperty("LOCATION");
          break;
          }
        }
      if (!executable.empty())
        {
        break;
        }
      }

    // now create a project file
    this->CreateProjectFile(outputDir, projectDir, projectName,
                            executable, cmakeFilePattern, fileToOpen);
    }
}

bool cmGlobalKdevelopGenerator
::CreateFilelistFile(const std::vector<cmLocalGenerator*>& lgs,
                     const std::string& outputDir,
                     const std::string& projectDirIn,
                     const std::string& projectname,
                     std::string& cmakeFilePattern,
                     std::string& fileToOpen)
{
  std::string projectDir = projectDirIn + "/";
  std::string filename = outputDir+ "/" + projectname +".kdevelop.filelist";

  std::set<cmStdString> files;
  std::string tmp;

  for (std::vector<cmLocalGenerator*>::const_iterator it=lgs.begin();
       it!=lgs.end(); it++)
    {
    cmMakefile* makefile=(*it)->GetMakefile();
    const std::vector<std::string>& listFiles=makefile->GetListFiles();
    for (std::vector<std::string>::const_iterator lt=listFiles.begin();
         lt!=listFiles.end(); lt++)
      {
      tmp=*lt;
      cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
      // make sure the file is part of this source tree
      if ((tmp[0]!='/') &&
          (strstr(tmp.c_str(),
                  cmake::GetCMakeFilesDirectoryPostSlash())==0))
        {
        files.insert(tmp);
        tmp=cmSystemTools::GetFilenameName(tmp);
        //add all files which dont match the default
        // */CMakeLists.txt;*cmake; to the file pattern
        if ((tmp!="CMakeLists.txt")
            && (strstr(tmp.c_str(), ".cmake")==0))
          {
          cmakeFilePattern+=tmp+";";
          }
        }
      }

    //get all sources
    cmTargets& targets=makefile->GetTargets();
    for (cmTargets::iterator ti = targets.begin();
         ti != targets.end(); ti++)
      {
      const std::vector<cmSourceFile*>& sources=ti->second.GetSourceFiles();
      for (std::vector<cmSourceFile*>::const_iterator si=sources.begin();
           si!=sources.end(); si++)
        {
        tmp=(*si)->GetFullPath();
        std::string headerBasename=cmSystemTools::GetFilenamePath(tmp);
        headerBasename+="/";
        headerBasename+=cmSystemTools::GetFilenameWithoutExtension(tmp);

        cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");

        if ((tmp[0]!='/')  &&
            (strstr(tmp.c_str(),
                  cmake::GetCMakeFilesDirectoryPostSlash())==0) &&
           (cmSystemTools::GetFilenameExtension(tmp)!=".moc"))
          {
          files.insert(tmp);

          // check if there's a matching header around
          for(std::vector<std::string>::const_iterator
                ext = makefile->GetHeaderExtensions().begin();
              ext !=  makefile->GetHeaderExtensions().end(); ++ext)
            {
            std::string hname=headerBasename;
            hname += ".";
            hname += *ext;
            if(cmSystemTools::FileExists(hname.c_str()))
              {
              cmSystemTools::ReplaceString(hname, projectDir.c_str(), "");
              files.insert(hname);
              break;
              }
            }
          }
        }
      for (std::vector<std::string>::const_iterator lt=listFiles.begin();
           lt!=listFiles.end(); lt++)
        {
        tmp=*lt;
        cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
        if ((tmp[0]!='/') &&
            (strstr(tmp.c_str(),
                    cmake::GetCMakeFilesDirectoryPostSlash())==0))
          {
          files.insert(tmp.c_str());
          }
        }
      }
    }

  //check if the output file already exists and read it
  //insert all files which exist into the set of files
  std::ifstream oldFilelist(filename.c_str());
  if (oldFilelist)
    {
    while (cmSystemTools::GetLineFromStream(oldFilelist, tmp))
      {
      if (tmp[0]=='/')
        {
        continue;
        }
      std::string completePath=projectDir+tmp;
      if (cmSystemTools::FileExists(completePath.c_str()))
        {
        files.insert(tmp);
        }
      }
    oldFilelist.close();
    }

  //now write the new filename
  cmGeneratedFileStream fout(filename.c_str());
  if(!fout)
    {
    return false;
    }

  fileToOpen="";
  for (std::set<cmStdString>::const_iterator it=files.begin();
       it!=files.end(); it++)
    {
    // get the full path to the file
    tmp=cmSystemTools::CollapseFullPath(it->c_str(), projectDir.c_str());
    // just select the first source file
    if (fileToOpen.empty())
    {
       std::string ext = cmSystemTools::GetFilenameExtension(tmp);
       if ((ext==".c") || (ext==".cc") || (ext==".cpp")  || (ext==".cxx")
           || (ext==".C") || (ext==".h") || (ext==".hpp"))
       {
       fileToOpen=tmp;
       }
    }
    // make it relative to the project dir
    cmSystemTools::ReplaceString(tmp, projectDir.c_str(), "");
    // only put relative paths
    if (tmp.size() && tmp[0] != '/')
      {
      fout << tmp.c_str() <<"\n";
      }
    }
  return true;
}


/* create the project file, if it already exists, merge it with the
existing one, otherwise create a new one */
void cmGlobalKdevelopGenerator
::CreateProjectFile(const std::string& outputDir,
                    const std::string& projectDir,
                    const std::string& projectname,
                    const std::string& executable,
                    const std::string& cmakeFilePattern,
                    const std::string& fileToOpen)
{
  this->Blacklist.clear();

  std::string filename=outputDir+"/";
  filename+=projectname+".kdevelop";
  std::string sessionFilename=outputDir+"/";
  sessionFilename+=projectname+".kdevses";

  if (cmSystemTools::FileExists(filename.c_str()))
    {
    this->MergeProjectFiles(outputDir, projectDir, filename,
                            executable, cmakeFilePattern,
                            fileToOpen, sessionFilename);
    }
  else
    {
    // add all subdirectories which are cmake build directories to the
    // kdevelop blacklist so they are not monitored for added or removed files
    // since this is handled by adding files to the cmake files
    cmsys::Directory d;
    if (d.Load(projectDir.c_str()))
      {
      size_t numf = d.GetNumberOfFiles();
      for (unsigned int i = 0; i < numf; i++)
        {
        std::string nextFile = d.GetFile(i);
        if ((nextFile!=".") && (nextFile!=".."))
          {
          std::string tmp = projectDir;
          tmp += "/";
          tmp += nextFile;
          if (cmSystemTools::FileIsDirectory(tmp.c_str()))
            {
            tmp += "/CMakeCache.txt";
            if ((nextFile == "CMakeFiles")
                || (cmSystemTools::FileExists(tmp.c_str())))
              {
              this->Blacklist.push_back(nextFile);
              }
            }
          }
        }
      }
    this->CreateNewProjectFile(outputDir, projectDir, filename,
                               executable, cmakeFilePattern,
                               fileToOpen, sessionFilename);
    }

}

void cmGlobalKdevelopGenerator
::MergeProjectFiles(const std::string& outputDir,
                    const std::string& projectDir,
                    const std::string& filename,
                    const std::string& executable,
                    const std::string& cmakeFilePattern,
                    const std::string& fileToOpen,
                    const std::string& sessionFilename)
{
  std::ifstream oldProjectFile(filename.c_str());
  if (!oldProjectFile)
    {
    this->CreateNewProjectFile(outputDir, projectDir, filename,
                               executable, cmakeFilePattern,
                               fileToOpen, sessionFilename);
    return;
    }

  /* Read the existing project file (line by line), copy all lines
    into the new project file, except the ones which can be reliably
    set from contents of the CMakeLists.txt */
  std::string tmp;
  std::vector<std::string> lines;
  while (cmSystemTools::GetLineFromStream(oldProjectFile, tmp))
    {
    lines.push_back(tmp);
    }
  oldProjectFile.close();

  cmGeneratedFileStream fout(filename.c_str());
  if(!fout)
    {
    return;
    }

  for (std::vector<std::string>::const_iterator it=lines.begin();
       it!=lines.end(); it++)
    {
    const char* line=(*it).c_str();
    // skip these tags as they are always replaced
    if ((strstr(line, "<projectdirectory>")!=0)
        || (strstr(line, "<projectmanagement>")!=0)
        || (strstr(line, "<absoluteprojectpath>")!=0)
        || (strstr(line, "<filelistdirectory>")!=0)
        || (strstr(line, "<buildtool>")!=0)
        || (strstr(line, "<builddir>")!=0))
      {
      continue;
      }

    // output the line from the file if it is not one of the above tags
    fout<<*it<<"\n";
    // if this is the <general> tag output the stuff that goes in the
    // general tag
    if (strstr(line, "<general>"))
      {
      fout<< "  <projectmanagement>KDevCustomProject</projectmanagement>\n";
      fout<< "  <projectdirectory>" <<projectDir.c_str()
          << "</projectdirectory>\n";   //this one is important
      fout<<"  <absoluteprojectpath>true</absoluteprojectpath>\n";
      //and this one
      }
    // inside kdevcustomproject the <filelistdirectory> must be put
    if (strstr(line, "<kdevcustomproject>"))
      {
      fout<<"    <filelistdirectory>"<<outputDir.c_str()
          <<"</filelistdirectory>\n";
      }
    // buildtool and builddir go inside <build>
    if (strstr(line, "<build>"))
      {
      fout<<"      <buildtool>make</buildtool>\n";
      fout<<"      <builddir>"<<outputDir.c_str()<<"</builddir>\n";
      }
    }
}

void cmGlobalKdevelopGenerator
::CreateNewProjectFile(const std::string& outputDir,
                       const std::string& projectDir,
                       const std::string& filename,
                       const std::string& executable,
                       const std::string& cmakeFilePattern,
                       const std::string& fileToOpen,
                       const std::string& sessionFilename)
{
  cmGeneratedFileStream fout(filename.c_str());
  if(!fout)
    {
    return;
    }

  // check for a version control system
  bool hasSvn = cmSystemTools::FileExists((projectDir + "/.svn").c_str());
  bool hasCvs = cmSystemTools::FileExists((projectDir + "/CVS").c_str());

  bool enableCxx = (this->GlobalGenerator->GetLanguageEnabled("C")
                          || this->GlobalGenerator->GetLanguageEnabled("CXX"));
  bool enableFortran = this->GlobalGenerator->GetLanguageEnabled("Fortran");
  std::string primaryLanguage = "C++";
  if (enableFortran && !enableCxx)
    {
    primaryLanguage="Fortran77";
    }

  fout<<"<?xml version = '1.0'?>\n"
        "<kdevelop>\n"
        "  <general>\n"
        "  <author></author>\n"
        "  <email></email>\n"
        "  <version>$VERSION$</version>\n"
        "  <projectmanagement>KDevCustomProject</projectmanagement>\n"
        "  <primarylanguage>" << primaryLanguage << "</primarylanguage>\n"
        "  <ignoreparts/>\n"
        "  <projectdirectory>" << projectDir.c_str() <<
        "</projectdirectory>\n";   //this one is important
  fout<<"  <absoluteprojectpath>true</absoluteprojectpath>\n"; //and this one

  // setup additional languages
  fout<<"  <secondaryLanguages>\n";
  if (enableFortran && enableCxx)
    {
    fout<<"     <language>Fortran</language>\n";
    }
  if (enableCxx)
    {
    fout<<"     <language>C</language>\n";
    }
  fout<<"  </secondaryLanguages>\n";

  if (hasSvn)
    {
    fout << "  <versioncontrol>kdevsubversion</versioncontrol>\n";
    }
  else if (hasCvs)
    {
    fout << "  <versioncontrol>kdevcvsservice</versioncontrol>\n";
    }

  fout<<"  </general>\n"
        "  <kdevcustomproject>\n"
        "    <filelistdirectory>" << outputDir.c_str() <<
        "</filelistdirectory>\n"
        "    <run>\n"
        "      <mainprogram>" << executable.c_str() << "</mainprogram>\n"
        "      <directoryradio>custom</directoryradio>\n"
        "      <customdirectory>"<<outputDir.c_str()<<"</customdirectory>\n"
        "      <programargs></programargs>\n"
        "      <terminal>false</terminal>\n"
        "      <autocompile>true</autocompile>\n"
        "      <envvars/>\n"
        "    </run>\n"
        "    <build>\n"
        "      <buildtool>make</buildtool>\n"; //this one is important
  fout<<"      <builddir>"<<outputDir.c_str()<<"</builddir>\n";  //and this one
  fout<<"    </build>\n"
        "    <make>\n"
        "      <abortonerror>false</abortonerror>\n"
        "      <numberofjobs>1</numberofjobs>\n"
        "      <dontact>false</dontact>\n"
        "      <makebin>" << this->GlobalGenerator->GetLocalGenerators()[0]->
            GetMakefile()->GetRequiredDefinition("CMAKE_BUILD_TOOL")
            << " </makebin>\n"
        "      <selectedenvironment>default</selectedenvironment>\n"
        "      <environments>\n"
        "        <default>\n"
        "          <envvar value=\"1\" name=\"VERBOSE\" />\n"
        "          <envvar value=\"1\" name=\"CMAKE_NO_VERBOSE\" />\n"
        "        </default>\n"
        "      </environments>\n"
        "    </make>\n";

  fout<<"    <blacklist>\n";
  for(std::vector<std::string>::const_iterator dirIt=this->Blacklist.begin();
      dirIt != this->Blacklist.end();
      ++dirIt)
    {
    fout<<"      <path>" << dirIt->c_str() << "</path>\n";
    }
  fout<<"    </blacklist>\n";

  fout<<"  </kdevcustomproject>\n"
        "  <kdevfilecreate>\n"
        "    <filetypes/>\n"
        "    <useglobaltypes>\n"
        "      <type ext=\"ui\" />\n"
        "      <type ext=\"cpp\" />\n"
        "      <type ext=\"h\" />\n"
        "    </useglobaltypes>\n"
        "  </kdevfilecreate>\n"
        "  <kdevdoctreeview>\n"
        "    <projectdoc>\n"
        "      <userdocDir>html/</userdocDir>\n"
        "      <apidocDir>html/</apidocDir>\n"
        "    </projectdoc>\n"
        "    <ignoreqt_xml/>\n"
        "    <ignoredoxygen/>\n"
        "    <ignorekdocs/>\n"
        "    <ignoretocs/>\n"
        "    <ignoredevhelp/>\n"
        "  </kdevdoctreeview>\n";

  if (enableCxx)
    {
    fout<<"  <cppsupportpart>\n"
          "    <filetemplates>\n"
          "      <interfacesuffix>.h</interfacesuffix>\n"
          "      <implementationsuffix>.cpp</implementationsuffix>\n"
          "    </filetemplates>\n"
          "  </cppsupportpart>\n"
          "  <kdevcppsupport>\n"
          "    <codecompletion>\n"
          "      <includeGlobalFunctions>true</includeGlobalFunctions>\n"
          "      <includeTypes>true</includeTypes>\n"
          "      <includeEnums>true</includeEnums>\n"
          "      <includeTypedefs>false</includeTypedefs>\n"
          "      <automaticCodeCompletion>true</automaticCodeCompletion>\n"
          "      <automaticArgumentsHint>true</automaticArgumentsHint>\n"
          "      <automaticHeaderCompletion>true</automaticHeaderCompletion>\n"
          "      <codeCompletionDelay>250</codeCompletionDelay>\n"
          "      <argumentsHintDelay>400</argumentsHintDelay>\n"
          "      <headerCompletionDelay>250</headerCompletionDelay>\n"
          "    </codecompletion>\n"
          "    <references/>\n"
          "  </kdevcppsupport>\n";
    }

  if (enableFortran)
    {
    fout<<"  <kdevfortransupport>\n"
          "    <ftnchek>\n"
          "      <division>false</division>\n"
          "      <extern>false</extern>\n"
          "      <declare>false</declare>\n"
          "      <pure>false</pure>\n"
          "      <argumentsall>false</argumentsall>\n"
          "      <commonall>false</commonall>\n"
          "      <truncationall>false</truncationall>\n"
          "      <usageall>false</usageall>\n"
          "      <f77all>false</f77all>\n"
          "      <portabilityall>false</portabilityall>\n"
          "      <argumentsonly/>\n"
          "      <commononly/>\n"
          "      <truncationonly/>\n"
          "      <usageonly/>\n"
          "      <f77only/>\n"
          "      <portabilityonly/>\n"
          "    </ftnchek>\n"
          "  </kdevfortransupport>\n";
    }

  // set up file groups. maybe this can be used with the CMake SOURCE_GROUP()
  // command
  fout<<"  <kdevfileview>\n"
        "    <groups>\n"
        "      <group pattern=\"" << cmakeFilePattern.c_str() <<
        "\" name=\"CMake\" />\n";

  if (enableCxx)
    {
    fout<<"      <group pattern=\"*.h;*.hxx;*.hpp\" name=\"Header\" />\n"
          "      <group pattern=\"*.c\" name=\"C Sources\" />\n"
          "      <group pattern=\"*.cpp;*.C;*.cxx;*.cc\" name=\"C++ Sources\""
          "/>\n";
    }

  if (enableFortran)
    {
    fout<<"      <group pattern=\"*.f;*.F;*.f77;*.F77;*.f90;*.F90;*.for;*.f95;"
          "*.F95\" name=\"Fortran Sources\" />\n";
    }

  fout<<"      <group pattern=\"*.ui\" name=\"Qt Designer files\" />\n"
        "      <hidenonprojectfiles>true</hidenonprojectfiles>\n"
        "    </groups>\n"
        "    <tree>\n"
        "      <hidepatterns>*.o,*.lo,CVS,*~,cmake*</hidepatterns>\n"
        "      <hidenonprojectfiles>true</hidenonprojectfiles>\n"
        "    </tree>\n"
        "  </kdevfileview>\n"
        "</kdevelop>\n";

  if (sessionFilename.empty())
    {
    return;
    }

  // and a session file, so that kdevelop opens a file if it opens the
  // project the first time
  cmGeneratedFileStream devses(sessionFilename.c_str());
  if(!devses)
    {
    return;
    }
  devses<<"<?xml version = '1.0' encoding = \'UTF-8\'?>\n"
          "<!DOCTYPE KDevPrjSession>\n"
          "<KDevPrjSession>\n"
          " <DocsAndViews NumberOfDocuments=\"1\" >\n"
          "  <Doc0 NumberOfViews=\"1\" URL=\"file://" << fileToOpen.c_str() <<
          "\" >\n"
          "   <View0 line=\"0\" Type=\"Source\" />\n"
          "  </Doc0>\n"
          " </DocsAndViews>\n"
          "</KDevPrjSession>\n";
}

