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

#include <cstring>
#include <set>
#include <sstream>
#include <utility>

#include "cmsys/RegularExpression.hxx"

#include "cmGeneratedFileStream.h"
#include "cmGeneratorExpression.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmMessageType.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmake.h"

/*
Sublime Text 2 Generator
Author: Morné Chamberlain
This generator was initially based off of the CodeBlocks generator.

Some useful URLs:
Homepage:
http://www.sublimetext.com/

File format docs:
http://www.sublimetext.com/docs/2/projects.html
http://sublimetext.info/docs/en/reference/build_systems.html
*/

cmExternalMakefileProjectGeneratorFactory*
cmExtraSublimeTextGenerator::GetFactory()
{
  static cmExternalMakefileProjectGeneratorSimpleFactory<
    cmExtraSublimeTextGenerator>
    factory("Sublime Text 2", "Generates Sublime Text 2 project files.");

  if (factory.GetSupportedGlobalGenerators().empty()) {
#if defined(_WIN32)
    factory.AddSupportedGlobalGenerator("MinGW Makefiles");
    factory.AddSupportedGlobalGenerator("NMake Makefiles");
// disable until somebody actually tests it:
// factory.AddSupportedGlobalGenerator("MSYS Makefiles");
#endif
    factory.AddSupportedGlobalGenerator("Ninja");
    factory.AddSupportedGlobalGenerator("Unix Makefiles");
  }

  return &factory;
}

cmExtraSublimeTextGenerator::cmExtraSublimeTextGenerator()
{
  this->ExcludeBuildFolder = false;
}

void cmExtraSublimeTextGenerator::Generate()
{
  this->ExcludeBuildFolder = this->GlobalGenerator->GlobalSettingIsOn(
    "CMAKE_SUBLIME_TEXT_2_EXCLUDE_BUILD_TREE");
  this->EnvSettings = this->GlobalGenerator->GetSafeGlobalSetting(
    "CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS");

  // for each sub project in the project create a sublime text 2 project
  for (auto const& it : this->GlobalGenerator->GetProjectMap()) {
    // create a project file
    this->CreateProjectFile(it.second);
  }
}

void cmExtraSublimeTextGenerator::CreateProjectFile(
  const std::vector<cmLocalGenerator*>& lgs)
{
  std::string outputDir = lgs[0]->GetCurrentBinaryDirectory();
  std::string projectName = lgs[0]->GetProjectName();

  const std::string filename =
    outputDir + "/" + projectName + ".sublime-project";

  this->CreateNewProjectFile(lgs, filename);
}

void cmExtraSublimeTextGenerator::CreateNewProjectFile(
  const std::vector<cmLocalGenerator*>& lgs, const std::string& filename)
{
  const cmMakefile* mf = lgs[0]->GetMakefile();

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

  const std::string& sourceRootRelativeToOutput = cmSystemTools::RelativePath(
    lgs[0]->GetBinaryDirectory(), lgs[0]->GetSourceDirectory());
  // Write the folder entries to the project file
  fout << "{\n";
  fout << "\t\"folders\":\n\t[\n\t";
  if (!sourceRootRelativeToOutput.empty()) {
    fout << "\t{\n\t\t\t\"path\": \"" << sourceRootRelativeToOutput << "\"";
    const std::string& outputRelativeToSourceRoot =
      cmSystemTools::RelativePath(lgs[0]->GetSourceDirectory(),
                                  lgs[0]->GetBinaryDirectory());
    if ((!outputRelativeToSourceRoot.empty()) &&
        ((outputRelativeToSourceRoot.length() < 3) ||
         (outputRelativeToSourceRoot.substr(0, 3) != "../"))) {
      if (this->ExcludeBuildFolder) {
        fout << ",\n\t\t\t\"folder_exclude_patterns\": [\""
             << outputRelativeToSourceRoot << "\"]";
      }
    }
  } else {
    fout << "\t{\n\t\t\t\"path\": \"./\"";
  }
  fout << "\n\t\t}";
  // End of the folders section
  fout << "\n\t]";

  // Write the beginning of the build systems section to the project file
  fout << ",\n\t\"build_systems\":\n\t[\n\t";

  // Set of include directories over all targets (sublime text/sublimeclang
  // doesn't currently support these settings per build system, only project
  // wide
  MapSourceFileFlags sourceFileFlags;
  AppendAllTargets(lgs, mf, fout, sourceFileFlags);

  // End of build_systems
  fout << "\n\t]";
  std::string systemName = mf->GetSafeDefinition("CMAKE_SYSTEM_NAME");
  std::vector<std::string> tokens = cmExpandedList(this->EnvSettings);

  if (!this->EnvSettings.empty()) {
    fout << ",";
    fout << "\n\t\"env\":";
    fout << "\n\t{";
    fout << "\n\t\t" << systemName << ":";
    fout << "\n\t\t{";
    for (std::string const& t : tokens) {
      size_t const pos = t.find_first_of('=');

      if (pos != std::string::npos) {
        std::string varName = t.substr(0, pos);
        std::string varValue = t.substr(pos + 1);

        fout << "\n\t\t\t\"" << varName << "\":\"" << varValue << "\"";
      } else {
        std::ostringstream e;
        e << "Could not parse Env Vars specified in "
             "\"CMAKE_SUBLIME_TEXT_2_ENV_SETTINGS\""
          << ", corrupted string " << t;
        mf->IssueMessage(MessageType::FATAL_ERROR, e.str());
      }
    }
    fout << "\n\t\t}";
    fout << "\n\t}";
  }
  fout << "\n}";
}

void cmExtraSublimeTextGenerator::AppendAllTargets(
  const std::vector<cmLocalGenerator*>& lgs, const cmMakefile* mf,
  cmGeneratedFileStream& fout, MapSourceFileFlags& sourceFileFlags)
{
  const std::string& make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  std::string compiler;
  if (!lgs.empty()) {
    this->AppendTarget(fout, "all", lgs[0], nullptr, make.c_str(), mf,
                       compiler.c_str(), sourceFileFlags, true);
    this->AppendTarget(fout, "clean", lgs[0], nullptr, make.c_str(), mf,
                       compiler.c_str(), sourceFileFlags, false);
  }

  // add all executable and library targets and some of the GLOBAL
  // and UTILITY targets
  for (cmLocalGenerator* lg : lgs) {
    cmMakefile* makefile = lg->GetMakefile();
    const std::vector<cmGeneratorTarget*>& targets = lg->GetGeneratorTargets();
    for (cmGeneratorTarget* target : targets) {
      std::string targetName = target->GetName();
      switch (target->GetType()) {
        case cmStateEnums::GLOBAL_TARGET: {
          // Only add the global targets from CMAKE_BINARY_DIR,
          // not from the subdirs
          if (lg->GetCurrentBinaryDirectory() == lg->GetBinaryDirectory()) {
            this->AppendTarget(fout, targetName, lg, nullptr, make.c_str(),
                               makefile, compiler.c_str(), sourceFileFlags,
                               false);
          }
        } break;
        case cmStateEnums::UTILITY:
          // Add all utility targets, except the Nightly/Continuous/
          // Experimental-"sub"targets as e.g. NightlyStart
          if (((targetName.find("Nightly") == 0) &&
               (targetName != "Nightly")) ||
              ((targetName.find("Continuous") == 0) &&
               (targetName != "Continuous")) ||
              ((targetName.find("Experimental") == 0) &&
               (targetName != "Experimental"))) {
            break;
          }

          this->AppendTarget(fout, targetName, lg, nullptr, make.c_str(),
                             makefile, compiler.c_str(), sourceFileFlags,
                             false);
          break;
        case cmStateEnums::EXECUTABLE:
        case cmStateEnums::STATIC_LIBRARY:
        case cmStateEnums::SHARED_LIBRARY:
        case cmStateEnums::MODULE_LIBRARY:
        case cmStateEnums::OBJECT_LIBRARY: {
          this->AppendTarget(fout, targetName, lg, target, make.c_str(),
                             makefile, compiler.c_str(), sourceFileFlags,
                             false);
          std::string fastTarget = cmStrCat(targetName, "/fast");
          this->AppendTarget(fout, fastTarget, lg, target, make.c_str(),
                             makefile, compiler.c_str(), sourceFileFlags,
                             false);
        } break;
        default:
          break;
      }
    }
  }
}

void cmExtraSublimeTextGenerator::AppendTarget(
  cmGeneratedFileStream& fout, const std::string& targetName,
  cmLocalGenerator* lg, cmGeneratorTarget* target, const char* make,
  const cmMakefile* makefile, const char* /*compiler*/,
  MapSourceFileFlags& sourceFileFlags, bool firstTarget)
{

  if (target != nullptr) {
    std::vector<cmSourceFile*> sourceFiles;
    target->GetSourceFiles(sourceFiles,
                           makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
    for (cmSourceFile* sourceFile : sourceFiles) {
      auto sourceFileFlagsIter =
        sourceFileFlags.find(sourceFile->ResolveFullPath());
      if (sourceFileFlagsIter == sourceFileFlags.end()) {
        sourceFileFlagsIter =
          sourceFileFlags
            .insert(MapSourceFileFlags::value_type(
              sourceFile->ResolveFullPath(), std::vector<std::string>()))
            .first;
      }
      std::vector<std::string>& flags = sourceFileFlagsIter->second;
      std::string flagsString =
        this->ComputeFlagsForObject(sourceFile, lg, target);
      std::string definesString = this->ComputeDefines(sourceFile, lg, target);
      std::string includesString =
        this->ComputeIncludes(sourceFile, lg, target);
      flags.clear();
      cmsys::RegularExpression flagRegex;
      // Regular expression to extract compiler flags from a string
      // https://gist.github.com/3944250
      const char* regexString =
        R"((^|[ ])-[DIOUWfgs][^= ]+(=\"[^"]+\"|=[^"][^ ]+)?)";
      flagRegex.compile(regexString);
      std::string workString =
        cmStrCat(flagsString, " ", definesString, " ", includesString);
      while (flagRegex.find(workString)) {
        std::string::size_type start = flagRegex.start();
        if (workString[start] == ' ') {
          start++;
        }
        flags.push_back(workString.substr(start, flagRegex.end() - start));
        if (flagRegex.end() < workString.size()) {
          workString = workString.substr(flagRegex.end());
        } else {
          workString.clear();
        }
      }
    }
  }

  // Ninja uses ninja.build files (look for a way to get the output file name
  // from cmMakefile or something)
  std::string makefileName;
  if (this->GlobalGenerator->GetName() == "Ninja") {
    makefileName = "build.ninja";
  } else {
    makefileName = "Makefile";
  }
  if (!firstTarget) {
    fout << ",\n\t";
  }
  fout << "\t{\n\t\t\t\"name\": \"" << lg->GetProjectName() << " - "
       << targetName << "\",\n";
  fout << "\t\t\t\"cmd\": ["
       << this->BuildMakeCommand(make, makefileName.c_str(), targetName)
       << "],\n";
  fout << "\t\t\t\"working_dir\": \"${project_path}\",\n";
  fout << "\t\t\t\"file_regex\": \""
          "^(..[^:]*)(?::|\\\\()([0-9]+)(?::|\\\\))(?:([0-9]+):)?\\\\s*(.*)"
          "\"\n";
  fout << "\t\t}";
}

// Create the command line for building the given target using the selected
// make
std::string cmExtraSublimeTextGenerator::BuildMakeCommand(
  const std::string& make, const char* makefile, const std::string& target)
{
  std::string command = cmStrCat('"', make, '"');
  std::string generator = this->GlobalGenerator->GetName();
  if (generator == "NMake Makefiles") {
    std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
    command += R"(, "/NOLOGO", "/f", ")";
    command += makefileName + "\"";
    command += ", \"" + target + "\"";
  } else if (generator == "Ninja") {
    std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
    command += R"(, "-f", ")";
    command += makefileName + "\"";
    command += ", \"" + target + "\"";
  } else {
    std::string makefileName;
    if (generator == "MinGW Makefiles") {
      // no escaping of spaces in this case, see
      // https://gitlab.kitware.com/cmake/cmake/issues/10014
      makefileName = makefile;
    } else {
      makefileName = cmSystemTools::ConvertToOutputPath(makefile);
    }
    command += R"(, "-f", ")";
    command += makefileName + "\"";
    command += ", \"" + target + "\"";
  }
  return command;
}

// TODO: Most of the code is picked up from the Ninja generator, refactor it.
std::string cmExtraSublimeTextGenerator::ComputeFlagsForObject(
  cmSourceFile* source, cmLocalGenerator* lg, cmGeneratorTarget* gtgt)
{
  std::string flags;
  std::string language = source->GetOrDetermineLanguage();
  if (language.empty()) {
    language = "C";
  }
  std::string const& config =
    lg->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");

  lg->GetTargetCompileFlags(gtgt, config, language, flags);

  // Add source file specific flags.
  cmGeneratorExpressionInterpreter genexInterpreter(lg, config, gtgt,
                                                    language);

  const std::string COMPILE_FLAGS("COMPILE_FLAGS");
  if (const char* cflags = source->GetProperty(COMPILE_FLAGS)) {
    lg->AppendFlags(flags, genexInterpreter.Evaluate(cflags, COMPILE_FLAGS));
  }

  const std::string COMPILE_OPTIONS("COMPILE_OPTIONS");
  if (const char* coptions = source->GetProperty(COMPILE_OPTIONS)) {
    lg->AppendCompileOptions(
      flags, genexInterpreter.Evaluate(coptions, COMPILE_OPTIONS));
  }

  return flags;
}

// TODO: Refactor with
// void cmMakefileTargetGenerator::WriteTargetLanguageFlags().
std::string cmExtraSublimeTextGenerator::ComputeDefines(
  cmSourceFile* source, cmLocalGenerator* lg, cmGeneratorTarget* target)

{
  std::set<std::string> defines;
  cmMakefile* makefile = lg->GetMakefile();
  const std::string& language = source->GetOrDetermineLanguage();
  const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
  cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
                                                    language);

  // Add preprocessor definitions for this target and configuration.
  lg->GetTargetDefines(target, config, language, defines);
  const std::string COMPILE_DEFINITIONS("COMPILE_DEFINITIONS");
  if (const char* compile_defs = source->GetProperty(COMPILE_DEFINITIONS)) {
    lg->AppendDefines(
      defines, genexInterpreter.Evaluate(compile_defs, COMPILE_DEFINITIONS));
  }

  std::string defPropName =
    cmStrCat("COMPILE_DEFINITIONS_", cmSystemTools::UpperCase(config));
  if (const char* config_compile_defs = source->GetProperty(defPropName)) {
    lg->AppendDefines(
      defines,
      genexInterpreter.Evaluate(config_compile_defs, COMPILE_DEFINITIONS));
  }

  std::string definesString;
  lg->JoinDefines(defines, definesString, language);

  return definesString;
}

std::string cmExtraSublimeTextGenerator::ComputeIncludes(
  cmSourceFile* source, cmLocalGenerator* lg, cmGeneratorTarget* target)

{
  std::vector<std::string> includes;
  cmMakefile* makefile = lg->GetMakefile();
  const std::string& language = source->GetOrDetermineLanguage();
  const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
  cmGeneratorExpressionInterpreter genexInterpreter(lg, config, target,
                                                    language);

  // Add include directories for this source file
  const std::string INCLUDE_DIRECTORIES("INCLUDE_DIRECTORIES");
  if (const char* cincludes = source->GetProperty(INCLUDE_DIRECTORIES)) {
    lg->AppendIncludeDirectories(
      includes, genexInterpreter.Evaluate(cincludes, INCLUDE_DIRECTORIES),
      *source);
  }

  // Add include directory flags.
  lg->GetIncludeDirectories(includes, target, language, config);

  std::string includesString =
    lg->GetIncludeFlags(includes, target, language, true, false, config);

  return includesString;
}

bool cmExtraSublimeTextGenerator::Open(const std::string& bindir,
                                       const std::string& projectName,
                                       bool dryRun)
{
  const char* sublExecutable =
    this->GlobalGenerator->GetCMakeInstance()->GetCacheDefinition(
      "CMAKE_SUBLIMETEXT_EXECUTABLE");
  if (!sublExecutable) {
    return false;
  }
  if (cmIsNOTFOUND(sublExecutable)) {
    return false;
  }

  std::string filename = bindir + "/" + projectName + ".sublime-project";
  if (dryRun) {
    return cmSystemTools::FileExists(filename, true);
  }

  return cmSystemTools::RunSingleCommand(
    { sublExecutable, "--project", filename });
}
