/* Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
   file Copyright.txt or https://cmake.org/licensing for details.  */
#include "cmGlobalKdevelopGenerator.h"

#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmXMLWriter.h"
#include "cmake.h"

#include <cmsys/Directory.hxx>
#include <cmsys/FStream.hxx>
#include <map>
#include <set>
#include <string.h>
#include <utility>

cmGlobalKdevelopGenerator::cmGlobalKdevelopGenerator()
  : cmExternalMakefileProjectGenerator()
{
}

cmExternalMakefileProjectGeneratorFactory*
cmGlobalKdevelopGenerator::GetFactory()
{
  static cmExternalMakefileProjectGeneratorSimpleFactory<
    cmGlobalKdevelopGenerator>
    factory("KDevelop3", "Generates KDevelop 3 project files.");

  if (factory.GetSupportedGlobalGenerators().empty()) {
    factory.AddSupportedGlobalGenerator("Unix Makefiles");
#ifdef CMAKE_USE_NINJA
    factory.AddSupportedGlobalGenerator("Ninja");
#endif

    factory.Aliases.push_back("KDevelop3");
  }

  return &factory;
}

void cmGlobalKdevelopGenerator::Generate()
{
  // for each sub project in the project create
  // a kdevelop project
  for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
         it = this->GlobalGenerator->GetProjectMap().begin();
       it != this->GlobalGenerator->GetProjectMap().end(); ++it) {
    std::string outputDir = it->second[0]->GetCurrentBinaryDirectory();
    std::string projectDir = it->second[0]->GetSourceDirectory();
    std::string projectName = it->second[0]->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++) {
      std::vector<cmGeneratorTarget*> const& targets =
        (*lg)->GetGeneratorTargets();
      for (std::vector<cmGeneratorTarget*>::const_iterator ti =
             targets.begin();
           ti != targets.end(); ti++) {
        if ((*ti)->GetType() == cmStateEnums::EXECUTABLE) {
          executable = (*ti)->GetLocation("");
          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<std::string> files;
  std::string tmp;

  std::vector<std::string> hdrExts =
    this->GlobalGenerator->GetCMakeInstance()->GetHeaderExtensions();

  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()) ==
           CM_NULLPTR)) {
        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") == CM_NULLPTR)) {
          cmakeFilePattern += tmp + ";";
        }
      }
    }

    // get all sources
    std::vector<cmGeneratorTarget*> targets = (*it)->GetGeneratorTargets();
    for (std::vector<cmGeneratorTarget*>::iterator ti = targets.begin();
         ti != targets.end(); ti++) {
      std::vector<cmSourceFile*> sources;
      cmGeneratorTarget* gt = *ti;
      gt->GetSourceFiles(sources, gt->Target->GetMakefile()->GetSafeDefinition(
                                    "CMAKE_BUILD_TYPE"));
      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()) ==
             CM_NULLPTR) &&
            (cmSystemTools::GetFilenameExtension(tmp) != ".moc")) {
          files.insert(tmp);

          // check if there's a matching header around
          for (std::vector<std::string>::const_iterator ext = hdrExts.begin();
               ext != hdrExts.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()) ==
             CM_NULLPTR)) {
          files.insert(tmp);
        }
      }
    }
  }

  // check if the output file already exists and read it
  // insert all files which exist into the set of files
  cmsys::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<std::string>::const_iterator it = files.begin();
       it != files.end(); it++) {
    // get the full path to the file
    tmp = cmSystemTools::CollapseFullPath(*it, 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.empty() && tmp[0] != '/') {
      fout << tmp << "\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)) {
      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)) {
            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)
{
  cmsys::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>") != CM_NULLPTR) ||
        (strstr(line, "<projectmanagement>") != CM_NULLPTR) ||
        (strstr(line, "<absoluteprojectpath>") != CM_NULLPTR) ||
        (strstr(line, "<filelistdirectory>") != CM_NULLPTR) ||
        (strstr(line, "<buildtool>") != CM_NULLPTR) ||
        (strstr(line, "<builddir>") != CM_NULLPTR)) {
      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
           << "</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
           << "</filelistdirectory>\n";
    }
    // buildtool and builddir go inside <build>
    if (strstr(line, "<build>")) {
      fout << "      <buildtool>make</buildtool>\n";
      fout << "      <builddir>" << outputDir << "</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;
  }
  cmXMLWriter xml(fout);

  // 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";
  }

  xml.StartDocument();
  xml.StartElement("kdevelop");
  xml.StartElement("general");

  xml.Element("author", "");
  xml.Element("email", "");
  xml.Element("version", "$VERSION$");
  xml.Element("projectmanagement", "KDevCustomProject");
  xml.Element("primarylanguage", primaryLanguage);
  xml.Element("ignoreparts");
  xml.Element("projectdirectory", projectDir); // this one is important
  xml.Element("absoluteprojectpath", "true");  // and this one

  // setup additional languages
  xml.StartElement("secondaryLanguages");
  if (enableFortran && enableCxx) {
    xml.Element("language", "Fortran");
  }
  if (enableCxx) {
    xml.Element("language", "C");
  }
  xml.EndElement();

  if (hasSvn) {
    xml.Element("versioncontrol", "kdevsubversion");
  } else if (hasCvs) {
    xml.Element("versioncontrol", "kdevcvsservice");
  }

  xml.EndElement(); // general
  xml.StartElement("kdevcustomproject");

  xml.Element("filelistdirectory", outputDir);

  xml.StartElement("run");
  xml.Element("mainprogram", executable);
  xml.Element("directoryradio", "custom");
  xml.Element("customdirectory", outputDir);
  xml.Element("programargs", "");
  xml.Element("terminal", "false");
  xml.Element("autocompile", "true");
  xml.Element("envvars");
  xml.EndElement();

  xml.StartElement("build");
  xml.Element("buildtool", "make");   // this one is important
  xml.Element("builddir", outputDir); // and this one
  xml.EndElement();

  xml.StartElement("make");
  xml.Element("abortonerror", "false");
  xml.Element("numberofjobs", 1);
  xml.Element("dontact", "false");
  xml.Element("makebin", this->GlobalGenerator->GetLocalGenerators()[0]
                           ->GetMakefile()
                           ->GetRequiredDefinition("CMAKE_MAKE_PROGRAM"));
  xml.Element("selectedenvironment", "default");

  xml.StartElement("environments");
  xml.StartElement("default");

  xml.StartElement("envvar");
  xml.Attribute("value", 1);
  xml.Attribute("name", "VERBOSE");
  xml.EndElement();

  xml.StartElement("envvar");
  xml.Attribute("value", 1);
  xml.Attribute("name", "CMAKE_NO_VERBOSE");
  xml.EndElement();

  xml.EndElement(); // default
  xml.EndElement(); // environments
  xml.EndElement(); // make

  xml.StartElement("blacklist");
  for (std::vector<std::string>::const_iterator dirIt =
         this->Blacklist.begin();
       dirIt != this->Blacklist.end(); ++dirIt) {
    xml.Element("path", *dirIt);
  }
  xml.EndElement();

  xml.EndElement(); // kdevcustomproject

  xml.StartElement("kdevfilecreate");
  xml.Element("filetypes");
  xml.StartElement("useglobaltypes");

  xml.StartElement("type");
  xml.Attribute("ext", "ui");
  xml.EndElement();

  xml.StartElement("type");
  xml.Attribute("ext", "cpp");
  xml.EndElement();

  xml.StartElement("type");
  xml.Attribute("ext", "h");
  xml.EndElement();

  xml.EndElement(); // useglobaltypes
  xml.EndElement(); // kdevfilecreate

  xml.StartElement("kdevdoctreeview");
  xml.StartElement("projectdoc");
  xml.Element("userdocDir", "html/");
  xml.Element("apidocDir", "html/");
  xml.EndElement(); // projectdoc
  xml.Element("ignoreqt_xml");
  xml.Element("ignoredoxygen");
  xml.Element("ignorekdocs");
  xml.Element("ignoretocs");
  xml.Element("ignoredevhelp");
  xml.EndElement(); // kdevdoctreeview;

  if (enableCxx) {
    xml.StartElement("cppsupportpart");
    xml.StartElement("filetemplates");
    xml.Element("interfacesuffix", ".h");
    xml.Element("implementationsuffix", ".cpp");
    xml.EndElement(); // filetemplates
    xml.EndElement(); // cppsupportpart

    xml.StartElement("kdevcppsupport");
    xml.StartElement("codecompletion");
    xml.Element("includeGlobalFunctions", "true");
    xml.Element("includeTypes", "true");
    xml.Element("includeEnums", "true");
    xml.Element("includeTypedefs", "false");
    xml.Element("automaticCodeCompletion", "true");
    xml.Element("automaticArgumentsHint", "true");
    xml.Element("automaticHeaderCompletion", "true");
    xml.Element("codeCompletionDelay", 250);
    xml.Element("argumentsHintDelay", 400);
    xml.Element("headerCompletionDelay", 250);
    xml.EndElement(); // codecompletion
    xml.Element("references");
    xml.EndElement(); // kdevcppsupport;
  }

  if (enableFortran) {
    xml.StartElement("kdevfortransupport");
    xml.StartElement("ftnchek");
    xml.Element("division", "false");
    xml.Element("extern", "false");
    xml.Element("declare", "false");
    xml.Element("pure", "false");
    xml.Element("argumentsall", "false");
    xml.Element("commonall", "false");
    xml.Element("truncationall", "false");
    xml.Element("usageall", "false");
    xml.Element("f77all", "false");
    xml.Element("portabilityall", "false");
    xml.Element("argumentsonly");
    xml.Element("commononly");
    xml.Element("truncationonly");
    xml.Element("usageonly");
    xml.Element("f77only");
    xml.Element("portabilityonly");
    xml.EndElement(); // ftnchek
    xml.EndElement(); // kdevfortransupport;
  }

  // set up file groups. maybe this can be used with the CMake SOURCE_GROUP()
  // command
  xml.StartElement("kdevfileview");
  xml.StartElement("groups");

  xml.StartElement("group");
  xml.Attribute("pattern", cmakeFilePattern);
  xml.Attribute("name", "CMake");
  xml.EndElement();

  if (enableCxx) {
    xml.StartElement("group");
    xml.Attribute("pattern", "*.h;*.hxx;*.hpp");
    xml.Attribute("name", "Header");
    xml.EndElement();

    xml.StartElement("group");
    xml.Attribute("pattern", "*.c");
    xml.Attribute("name", "C Sources");
    xml.EndElement();

    xml.StartElement("group");
    xml.Attribute("pattern", "*.cpp;*.C;*.cxx;*.cc");
    xml.Attribute("name", "C++ Sources");
    xml.EndElement();
  }

  if (enableFortran) {
    xml.StartElement("group");
    xml.Attribute("pattern",
                  "*.f;*.F;*.f77;*.F77;*.f90;*.F90;*.for;*.f95;*.F95");
    xml.Attribute("name", "Fortran Sources");
    xml.EndElement();
  }

  xml.StartElement("group");
  xml.Attribute("pattern", "*.ui");
  xml.Attribute("name", "Qt Designer files");
  xml.EndElement();

  xml.Element("hidenonprojectfiles", "true");
  xml.EndElement(); // groups

  xml.StartElement("tree");
  xml.Element("hidepatterns", "*.o,*.lo,CVS,*~,cmake*");
  xml.Element("hidenonprojectfiles", "true");
  xml.EndElement(); // tree

  xml.EndElement(); // kdevfileview
  xml.EndElement(); // kdevelop;
  xml.EndDocument();

  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;
  }
  cmXMLWriter sesxml(devses);
  sesxml.StartDocument("UTF-8");
  sesxml.Doctype("KDevPrjSession");
  sesxml.StartElement("KDevPrjSession");

  sesxml.StartElement("DocsAndViews");
  sesxml.Attribute("NumberOfDocuments", 1);

  sesxml.StartElement("Doc0");
  sesxml.Attribute("NumberOfViews", 1);
  sesxml.Attribute("URL", "file://" + fileToOpen);

  sesxml.StartElement("View0");
  sesxml.Attribute("line", 0);
  sesxml.Attribute("Type", "Source");
  sesxml.EndElement(); // View0

  sesxml.EndElement(); // Doc0
  sesxml.EndElement(); // DocsAndViews
  sesxml.EndElement(); // KDevPrjSession;
}
