/*============================================================================
  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 "cmExtraSublimeTextGenerator.h"
#include "cmake.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalUnixMakefileGenerator3.h"
#include "cmLocalGenerator.h"
#include "cmLocalUnixMakefileGenerator3.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmSystemTools.h"
#include "cmTarget.h"
#include "cmXMLSafe.h"

#include <cmsys/SystemTools.hxx>

/*
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
*/

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

cmExtraSublimeTextGenerator::cmExtraSublimeTextGenerator()
:cmExternalMakefileProjectGenerator()
{
#if defined(_WIN32)
  this->SupportedGlobalGenerators.push_back("MinGW Makefiles");
  this->SupportedGlobalGenerators.push_back("NMake Makefiles");
// disable until somebody actually tests it:
//  this->SupportedGlobalGenerators.push_back("MSYS Makefiles");
#endif
  this->SupportedGlobalGenerators.push_back("Ninja");
  this->SupportedGlobalGenerators.push_back("Unix Makefiles");
}


void cmExtraSublimeTextGenerator::Generate()
{
  // for each sub project in the project create a sublime text 2 project
  for (std::map<std::string, std::vector<cmLocalGenerator*> >::const_iterator
       it = this->GlobalGenerator->GetProjectMap().begin();
      it!= this->GlobalGenerator->GetProjectMap().end();
      ++it)
    {
    // create a project file
    this->CreateProjectFile(it->second);
    }
}


void cmExtraSublimeTextGenerator::CreateProjectFile(
                                     const std::vector<cmLocalGenerator*>& lgs)
{
  const cmMakefile* mf=lgs[0]->GetMakefile();
  std::string outputDir=mf->GetStartOutputDirectory();
  std::string projectName=mf->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.c_str());
  if(!fout)
    {
    return;
    }

  const std::string &sourceRootRelativeToOutput = cmSystemTools::RelativePath(
                     mf->GetHomeOutputDirectory(),
                     mf->GetHomeDirectory());
  // 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(mf->GetHomeDirectory(),
                                    mf->GetHomeOutputDirectory());
      if ((!outputRelativeToSourceRoot.empty()) &&
        ((outputRelativeToSourceRoot.length() < 3) ||
          (outputRelativeToSourceRoot.substr(0, 3) != "../")))
        {
        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]";
  fout << "\n\t}";
}


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

  // add all executable and library targets and some of the GLOBAL
  // and UTILITY targets
  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++)
      {
      switch(ti->second.GetType())
        {
        case cmTarget::GLOBAL_TARGET:
          {
          // Only add the global targets from CMAKE_BINARY_DIR,
          // not from the subdirs
          if (strcmp(makefile->GetStartOutputDirectory(),
                     makefile->GetHomeOutputDirectory())==0)
            {
            this->AppendTarget(fout, ti->first, *lg, 0,
                               make.c_str(), makefile, compiler.c_str(),
                               sourceFileFlags, false);
            }
          }
          break;
        case cmTarget::UTILITY:
          // Add all utility targets, except the Nightly/Continuous/
          // Experimental-"sub"targets as e.g. NightlyStart
          if (((ti->first.find("Nightly")==0)   &&(ti->first!="Nightly"))
             || ((ti->first.find("Continuous")==0)&&(ti->first!="Continuous"))
             || ((ti->first.find("Experimental")==0)
                                               && (ti->first!="Experimental")))
            {
            break;
            }

          this->AppendTarget(fout, ti->first, *lg, 0,
                             make.c_str(), makefile, compiler.c_str(),
                             sourceFileFlags, false);
          break;
        case cmTarget::EXECUTABLE:
        case cmTarget::STATIC_LIBRARY:
        case cmTarget::SHARED_LIBRARY:
        case cmTarget::MODULE_LIBRARY:
        case cmTarget::OBJECT_LIBRARY:
          {
          this->AppendTarget(fout, ti->first, *lg, &ti->second,
                             make.c_str(), makefile, compiler.c_str(),
                             sourceFileFlags, false);
          std::string fastTarget = ti->first;
          fastTarget += "/fast";
          this->AppendTarget(fout, fastTarget, *lg, &ti->second,
                             make.c_str(), makefile, compiler.c_str(),
                             sourceFileFlags, false);
          }
          break;
        default:
          break;
        }
      }
    }
}

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

  if (target != 0)
    {
      cmGeneratorTarget *gtgt = this->GlobalGenerator
                                    ->GetGeneratorTarget(target);
      std::vector<cmSourceFile*> sourceFiles;
      target->GetSourceFiles(sourceFiles,
                             makefile->GetSafeDefinition("CMAKE_BUILD_TYPE"));
      std::vector<cmSourceFile*>::const_iterator sourceFilesEnd =
        sourceFiles.end();
      for (std::vector<cmSourceFile*>::const_iterator iter =
        sourceFiles.begin(); iter != sourceFilesEnd; ++iter)
        {
          cmSourceFile* sourceFile = *iter;
          MapSourceFileFlags::iterator sourceFileFlagsIter =
            sourceFileFlags.find(sourceFile->GetFullPath());
          if (sourceFileFlagsIter == sourceFileFlags.end())
            {
            sourceFileFlagsIter =
              sourceFileFlags.insert(MapSourceFileFlags::value_type(
                sourceFile->GetFullPath(), std::vector<std::string>())).first;
            }
          std::vector<std::string>& flags = sourceFileFlagsIter->second;
          std::string flagsString =
            this->ComputeFlagsForObject(*iter, lg, target, gtgt);
          std::string definesString =
            this->ComputeDefines(*iter, lg, target, gtgt);
          flags.clear();
          cmsys::RegularExpression flagRegex;
          // Regular expression to extract compiler flags from a string
          // https://gist.github.com/3944250
          const char* regexString =
            "(^|[ ])-[DIOUWfgs][^= ]+(=\\\"[^\"]+\\\"|=[^\"][^ ]+)?";
          flagRegex.compile(regexString);
          std::string workString = flagsString + " " + definesString;
          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 = "";
                }
            }
        }
    }

  // 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\": \"" << makefile->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]+)?:? (.*)$\"\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 = "\"";
  command += make + "\"";
  std::string generator = this->GlobalGenerator->GetName();
  if (generator == "NMake Makefiles")
    {
    std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
    command += ", \"/NOLOGO\", \"/f\", \"";
    command += makefileName + "\"";
    command += ", \"VERBOSE=1\", \"";
    command += target;
    command += "\"";
    }
  else if (generator == "Ninja")
    {
    std::string makefileName = cmSystemTools::ConvertToOutputPath(makefile);
    command += ", \"-f\", \"";
    command += makefileName + "\"";
    command += ", \"-v\", \"";
    command += target;
    command += "\"";
    }
  else
    {
    std::string makefileName;
    if (generator == "MinGW Makefiles")
      {
        // no escaping of spaces in this case, see
        // http://public.kitware.com/Bug/view.php?id=10014
        makefileName = makefile;
      }
      else
      {
        makefileName = cmSystemTools::ConvertToOutputPath(makefile);
      }
    command += ", \"-f\", \"";
    command += makefileName + "\"";
    command += ", \"VERBOSE=1\", \"";
    command += target;
    command += "\"";
    }
  return command;
}

// TODO: Most of the code is picked up from the Ninja generator, refactor it.
std::string
cmExtraSublimeTextGenerator::ComputeFlagsForObject(cmSourceFile* source,
                                                   cmLocalGenerator* lg,
                                                   cmTarget *target,
                                                   cmGeneratorTarget* gtgt)
{
  std::string flags;

  cmMakefile *makefile = lg->GetMakefile();
  std::string language = source->GetLanguage();
  if (language.empty())
   {
   language = "C";
   }
  const std::string& config = makefile->GetSafeDefinition("CMAKE_BUILD_TYPE");
  // Add language-specific flags.
  lg->AddLanguageFlags(flags, language, config);

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

  // TODO: Fortran support.
  // // Fortran-specific flags computed for this target.
  // if(*l == "Fortran")
  //   {
  //   this->AddFortranFlags(flags);
  //   }

  // Add shared-library flags if needed.
  lg->AddCMP0018Flags(flags, target, language, config);

  // Add include directory flags.
  {
  std::vector<std::string> includes;
  lg->GetIncludeDirectories(includes, gtgt, language, config);
  std::string includeFlags =
    lg->GetIncludeFlags(includes, gtgt, language, true); // full include paths
  lg->AppendFlags(flags, includeFlags);
  }

  // Append old-style preprocessor definition flags.
  lg->AppendFlags(flags, makefile->GetDefineFlags());

  // Add target-specific flags.
  lg->AddCompileOptions(flags, target, language, config);

  // Add source file specific flags.
  lg->AppendFlags(flags, source->GetProperty("COMPILE_FLAGS"));

  // TODO: Handle Apple frameworks.

  return flags;
}

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

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

  // Add the export symbol definition for shared library objects.
  if(const char* exportMacro = target->GetExportMacro())
    {
    lg->AppendDefines(defines, exportMacro);
    }

  // Add preprocessor definitions for this target and configuration.
  lg->AddCompileDefinitions(defines, target, config);
  lg->AppendDefines(defines, source->GetProperty("COMPILE_DEFINITIONS"));
  {
  std::string defPropName = "COMPILE_DEFINITIONS_";
  defPropName += cmSystemTools::UpperCase(config);
  lg->AppendDefines(defines, source->GetProperty(defPropName));
  }

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

  return definesString;
}
