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

#include <cmsys/SystemTools.hxx>

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

cmExtraKateGenerator::cmExtraKateGenerator()
: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 cmExtraKateGenerator::Generate()
{
  const cmMakefile* mf
     = this->GlobalGenerator->GetLocalGenerators()[0]->GetMakefile();
  this->ProjectName = this->GenerateProjectName(mf->GetProjectName(),
                          mf->GetSafeDefinition("CMAKE_BUILD_TYPE"),
                          this->GetPathBasename(mf->GetHomeOutputDirectory()));
  this->UseNinja = (this->GlobalGenerator->GetName() == "Ninja");

  this->CreateKateProjectFile(mf);
  this->CreateDummyKateProjectFile(mf);
}


void cmExtraKateGenerator::CreateKateProjectFile(const cmMakefile* mf) const
{
  std::string filename = mf->GetHomeOutputDirectory();
  filename += "/.kateproject";
  cmGeneratedFileStream fout(filename.c_str());
  if (!fout)
    {
    return;
    }

  std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  std::string args = mf->GetSafeDefinition("CMAKE_KATE_MAKE_ARGUMENTS");

  fout <<
    "{\n"
    "\t\"name\": \"" << this->ProjectName << "\",\n"
    "\t\"directory\": \"" << mf->GetHomeDirectory() << "\",\n"
    "\t\"files\": [ { " << this->GenerateFilesString(mf) << "} ],\n";
  this->WriteTargets(mf, fout);
  fout << "}\n";
}


void
cmExtraKateGenerator::WriteTargets(const cmMakefile* mf,
                                   cmGeneratedFileStream& fout) const
{
  const std::string make = mf->GetRequiredDefinition("CMAKE_MAKE_PROGRAM");
  const std::string makeArgs = mf->GetSafeDefinition(
    "CMAKE_KATE_MAKE_ARGUMENTS");
  const char* homeOutputDir = mf->GetHomeOutputDirectory();

  fout <<
  "\t\"build\": {\n"
  "\t\t\"directory\": \"" << mf->GetHomeOutputDirectory() << "\",\n"
  "\t\t\"default_target\": \"all\",\n"
  "\t\t\"clean_target\": \"clean\",\n";

  // build, clean and quick are for the build plugin kate <= 4.12:
  fout << "\t\t\"build\": \"" << make << " -C \\\"" << homeOutputDir
       << "\\\" " << makeArgs << " " << "all\",\n";
  fout << "\t\t\"clean\": \"" << make << " -C \\\"" << homeOutputDir
       << "\\\" " << makeArgs << " " << "clean\",\n";
  fout << "\t\t\"quick\": \"" << make << " -C \\\"" << homeOutputDir
       << "\\\" " << makeArgs << " " << "install\",\n";

  // this is for kate >= 4.13:
  fout <<
  "\t\t\"targets\":[\n";

  this->AppendTarget(fout, "all", make, makeArgs,
                     homeOutputDir, homeOutputDir);
  this->AppendTarget(fout, "clean", make, makeArgs,
                     homeOutputDir, homeOutputDir);

  // add all executable and library targets and some of the GLOBAL
  // and UTILITY targets
  for (std::vector<cmLocalGenerator*>::const_iterator
       it = this->GlobalGenerator->GetLocalGenerators().begin();
       it != this->GlobalGenerator->GetLocalGenerators().end();
       ++it)
    {
    const cmTargets& targets = (*it)->GetMakefile()->GetTargets();
    cmMakefile* makefile=(*it)->GetMakefile();
    std::string currentDir = makefile->GetCurrentBinaryDirectory();
    bool topLevel = (currentDir == makefile->GetHomeOutputDirectory());

    for(cmTargets::const_iterator ti=targets.begin(); ti!=targets.end(); ++ti)
      {
      switch(ti->second.GetType())
        {
        case cmTarget::GLOBAL_TARGET:
          {
          bool insertTarget = false;
          // Only add the global targets from CMAKE_BINARY_DIR,
          // not from the subdirs
          if (topLevel)
            {
            insertTarget = true;
            // only add the "edit_cache" target if it's not ccmake, because
            // this will not work within the IDE
            if (ti->first == "edit_cache")
              {
              const char* editCommand = makefile->GetDefinition
              ("CMAKE_EDIT_COMMAND");
              if (editCommand == 0)
                {
                insertTarget = false;
                }
              else if (strstr(editCommand, "ccmake")!=NULL)
                {
                insertTarget = false;
                }
              }
            }
          if (insertTarget)
            {
            this->AppendTarget(fout, ti->first, make, makeArgs,
                               currentDir, homeOutputDir);
            }
        }
        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, make, makeArgs,
                               currentDir, homeOutputDir);
          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, make, makeArgs,
                             currentDir, homeOutputDir);
          std::string fastTarget = ti->first;
          fastTarget += "/fast";
          this->AppendTarget(fout, fastTarget, make, makeArgs,
                             currentDir, homeOutputDir);

        }
        break;
        default:
          break;
      }
    }

    //insert rules for compiling, preprocessing and assembling individual files
    std::vector<std::string> objectFileTargets;
    (*it)->GetIndividualFileTargets(objectFileTargets);
    for(std::vector<std::string>::const_iterator fit=objectFileTargets.begin();
        fit != objectFileTargets.end();
        ++fit)
      {
      this->AppendTarget(fout, *fit, make, makeArgs, currentDir,homeOutputDir);
      }
  }

  fout <<
  "\t] }\n";
}


void
cmExtraKateGenerator::AppendTarget(cmGeneratedFileStream& fout,
                                   const std::string&     target,
                                   const std::string&     make,
                                   const std::string&     makeArgs,
                                   const std::string&     path,
                                   const char*            homeOutputDir
                                  ) const
{
  static char JsonSep = ' ';

  fout <<
    "\t\t\t" << JsonSep << "{\"name\":\"" << target << "\", "
    "\"build_cmd\":\"" << make
               << " -C \\\"" << (this->UseNinja ? homeOutputDir : path.c_str())
               << "\\\" " << makeArgs << " "
               << target << "\"}\n";

  JsonSep = ',';
}



void
cmExtraKateGenerator::CreateDummyKateProjectFile(const cmMakefile* mf) const
{
  std::string filename = mf->GetHomeOutputDirectory();
  filename += "/";
  filename += this->ProjectName;
  filename += ".kateproject";
  cmGeneratedFileStream fout(filename.c_str());
  if (!fout)
    {
    return;
    }

  fout << "#Generated by " << cmSystemTools::GetCMakeCommand()
       << ", do not edit.\n";
}


std::string
cmExtraKateGenerator::GenerateFilesString(const cmMakefile* mf) const
{
  std::string s = mf->GetHomeDirectory();
  s += "/.git";
  if(cmSystemTools::FileExists(s.c_str()))
  {
    return std::string("\"git\": 1 ");
  }

  s = mf->GetHomeDirectory();
  s += "/.svn";
  if(cmSystemTools::FileExists(s.c_str()))
  {
    return std::string("\"svn\": 1 ");
  }

  s = mf->GetHomeDirectory();
  s += "/";

  std::set<std::string> files;
  std::string tmp;
  const std::vector<cmLocalGenerator *>& lgs =
                                   this->GlobalGenerator->GetLocalGenerators();

  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;
        {
        files.insert(tmp);
        }
      }

    const std::vector<cmSourceFile*>& sources = makefile->GetSourceFiles();
    for (std::vector<cmSourceFile*>::const_iterator sfIt = sources.begin();
         sfIt != sources.end(); sfIt++)
      {
      cmSourceFile* sf = *sfIt;
      if (sf->GetPropertyAsBool("GENERATED"))
        {
        continue;
        }

      tmp = sf->GetFullPath();
      files.insert(tmp);
      }
    }

  const char* sep = "";
  tmp = "\"list\": [";
  for(std::set<std::string>::const_iterator it = files.begin();
      it != files.end(); ++it)
    {
    tmp += sep;
    tmp += " \"";
    tmp += *it;
    tmp += "\"";
    sep = ",";
    }
  tmp += "] ";

  return tmp;
}


std::string cmExtraKateGenerator::GenerateProjectName(const std::string& name,
                                                 const std::string& type,
                                                 const std::string& path) const
{
  return name + (type.empty() ? "" : "-") + type + "@" + path;
}


std::string cmExtraKateGenerator::GetPathBasename(const std::string& path)const
{
  std::string outputBasename = path;
  while (!outputBasename.empty() &&
         (outputBasename[outputBasename.size() - 1] == '/' ||
          outputBasename[outputBasename.size() - 1] == '\\'))
    {
    outputBasename.resize(outputBasename.size() - 1);
    }
  std::string::size_type loc = outputBasename.find_last_of("/\\");
  if (loc != std::string::npos)
    {
    outputBasename = outputBasename.substr(loc + 1);
    }

  return outputBasename;
}
