/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2015 Geoffrey Viola <geoffrey.viola@asirobots.com>

  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 "cmGlobalGhsMultiGenerator.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
#include "cmVersion.h"
#include "cmGeneratedFileStream.h"
#include "cmGhsMultiTargetGenerator.h"
#include <cmsys/SystemTools.hxx>
#include <cmAlgorithms.h>

const char *cmGlobalGhsMultiGenerator::FILE_EXTENSION = ".gpj";
const char *cmGlobalGhsMultiGenerator::DEFAULT_MAKE_PROGRAM = "gbuild";

cmGlobalGhsMultiGenerator::cmGlobalGhsMultiGenerator(cmake* cm)
  : cmGlobalGenerator(cm), OSDirRelative(false)
{
  this->GhsBuildCommandInitialized = false;
}

cmGlobalGhsMultiGenerator::~cmGlobalGhsMultiGenerator()
{
  cmDeleteAll(TargetFolderBuildStreams);
}

cmLocalGenerator *
cmGlobalGhsMultiGenerator::CreateLocalGenerator(cmLocalGenerator* parent,
                                                cmState::Snapshot snapshot)
{
  return new cmLocalGhsMultiGenerator(this, parent, snapshot);
}

void cmGlobalGhsMultiGenerator::GetDocumentation(cmDocumentationEntry &entry)
{
  entry.Name = GetActualName();
  entry.Brief =
    "Generates Green Hills MULTI files (experimental, work-in-progress).";
}

void cmGlobalGhsMultiGenerator::EnableLanguage(
  std::vector<std::string> const &l, cmMakefile *mf, bool optional)
{
  mf->AddDefinition("CMAKE_SYSTEM_NAME", "GHS-MULTI");
  mf->AddDefinition("CMAKE_SYSTEM_PROCESSOR", "ARM");

  const std::string ghsCompRoot(GetCompRoot());
  mf->AddDefinition("GHS_COMP_ROOT", ghsCompRoot.c_str());
  std::string ghsCompRootStart =
    0 == ghsCompRootStart.size() ? "" : ghsCompRoot + "/";
  mf->AddDefinition("CMAKE_C_COMPILER",
                    std::string(ghsCompRootStart + "ccarm.exe").c_str());
  mf->AddDefinition("CMAKE_C_COMPILER_ID_RUN", "TRUE");
  mf->AddDefinition("CMAKE_C_COMPILER_ID", "GHS");
  mf->AddDefinition("CMAKE_C_COMPILER_FORCED", "TRUE");

  mf->AddDefinition("CMAKE_CXX_COMPILER",
                    std::string(ghsCompRootStart + "cxarm.exe").c_str());
  mf->AddDefinition("CMAKE_CXX_COMPILER_ID_RUN", "TRUE");
  mf->AddDefinition("CMAKE_CXX_COMPILER_ID", "GHS");
  mf->AddDefinition("CMAKE_CXX_COMPILER_FORCED", "TRUE");

  if (!ghsCompRoot.empty())
    {
    static const char *compPreFix = "comp_";
    std::string compFilename =
      cmsys::SystemTools::FindLastString(ghsCompRoot.c_str(), compPreFix);
    cmsys::SystemTools::ReplaceString(compFilename, compPreFix, "");
    mf->AddDefinition("CMAKE_SYSTEM_VERSION", compFilename.c_str());
    }

  mf->AddDefinition("GHSMULTI", "1"); // identifier for user CMake files
  this->cmGlobalGenerator::EnableLanguage(l, mf, optional);
}

void cmGlobalGhsMultiGenerator::FindMakeProgram(cmMakefile *mf)
{
  // The GHS generator knows how to lookup its build tool
  // directly instead of needing a helper module to do it, so we
  // do not actually need to put CMAKE_MAKE_PROGRAM into the cache.
  if (cmSystemTools::IsOff(mf->GetDefinition("CMAKE_MAKE_PROGRAM")))
    {
    mf->AddDefinition("CMAKE_MAKE_PROGRAM",
                      this->GetGhsBuildCommand().c_str());
    }
}

std::string const &cmGlobalGhsMultiGenerator::GetGhsBuildCommand()
{
  if (!this->GhsBuildCommandInitialized)
    {
    this->GhsBuildCommandInitialized = true;
    this->GhsBuildCommand = this->FindGhsBuildCommand();
    }
  return this->GhsBuildCommand;
}

std::string cmGlobalGhsMultiGenerator::FindGhsBuildCommand()
{
  std::vector<std::string> userPaths;
  userPaths.push_back(this->GetCompRoot());
  std::string makeProgram =
    cmSystemTools::FindProgram(DEFAULT_MAKE_PROGRAM, userPaths);
  if (makeProgram.empty())
    {
    makeProgram = DEFAULT_MAKE_PROGRAM;
    }
  return makeProgram;
}

std::string cmGlobalGhsMultiGenerator::GetCompRoot()
{
  std::string output;

  const std::vector<std::string>
    potentialDirsHardPaths(GetCompRootHardPaths());
  const std::vector<std::string> potentialDirsRegistry(GetCompRootRegistry());

  std::vector<std::string> potentialDirsComplete;
  potentialDirsComplete.insert(potentialDirsComplete.end(),
                               potentialDirsHardPaths.begin(),
                               potentialDirsHardPaths.end());
  potentialDirsComplete.insert(potentialDirsComplete.end(),
                               potentialDirsRegistry.begin(),
                               potentialDirsRegistry.end());

  // Use latest version
  std::string outputDirName;
  for (std::vector<std::string>::const_iterator potentialDirsCompleteIt =
         potentialDirsComplete.begin();
       potentialDirsCompleteIt != potentialDirsComplete.end();
       ++potentialDirsCompleteIt)
    {
    const std::string dirName(
      cmsys::SystemTools::GetFilenameName(*potentialDirsCompleteIt));
    if (dirName.compare(outputDirName) > 0)
      {
      output = *potentialDirsCompleteIt;
      outputDirName = dirName;
      }
    }

  return output;
}

std::vector<std::string> cmGlobalGhsMultiGenerator::GetCompRootHardPaths()
{
  std::vector<std::string> output;
  cmSystemTools::Glob("C:/ghs", "comp_[^;]+", output);
  for (std::vector<std::string>::iterator outputIt = output.begin();
       outputIt != output.end(); ++outputIt)
    {
    *outputIt = "C:/ghs/" + *outputIt;
    }
  return output;
}

std::vector<std::string> cmGlobalGhsMultiGenerator::GetCompRootRegistry()
{
  std::vector<std::string> output(2);
  cmsys::SystemTools::ReadRegistryValue(
    "HKEY_LOCAL_"
    "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\"
    "Windows\\CurrentVersion\\Uninstall\\"
    "GreenHillsSoftwared771f1b4;InstallLocation",
    output[0]);
  cmsys::SystemTools::ReadRegistryValue(
    "HKEY_LOCAL_"
    "MACHINE\\SOFTWARE\\Wow6432Node\\Microsoft\\"
    "Windows\\CurrentVersion\\Uninstall\\"
    "GreenHillsSoftware9881cef6;InstallLocation",
    output[1]);
  return output;
}

void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
  std::string const &filepath, cmGeneratedFileStream **filestream)
{
  // Get a stream where to generate things.
  if (NULL == *filestream)
    {
    *filestream = new cmGeneratedFileStream(filepath.c_str());
    if (NULL != *filestream)
      {
      OpenBuildFileStream(*filestream);
      }
    }
}

void cmGlobalGhsMultiGenerator::OpenBuildFileStream(
  cmGeneratedFileStream *filestream)
{
  *filestream << "#!gbuild" << std::endl;
}

void cmGlobalGhsMultiGenerator::OpenBuildFileStream()
{
  // Compute GHS MULTI's build file path.
  std::string buildFilePath =
    this->GetCMakeInstance()->GetHomeOutputDirectory();
  buildFilePath += "/";
  buildFilePath += "default";
  buildFilePath += FILE_EXTENSION;

  this->Open(std::string(""), buildFilePath, &this->TargetFolderBuildStreams);
  OpenBuildFileStream(GetBuildFileStream());

  char const *osDir =
    this->GetCMakeInstance()->GetCacheDefinition("GHS_OS_DIR");
  if (NULL == osDir)
    {
    osDir = "";
    cmSystemTools::Error("GHS_OS_DIR cache variable must be set");
    }
  else
    {
    this->GetCMakeInstance()->MarkCliAsUsed("GHS_OS_DIR");
    }
  std::string fOSDir(this->trimQuotes(osDir));
  cmSystemTools::ReplaceString(fOSDir, "\\", "/");
  if (!fOSDir.empty() && ('c' == fOSDir[0] || 'C' == fOSDir[0]))
    {
    this->OSDirRelative = false;
    }
  else
    {
    this->OSDirRelative = true;
    }

  char const *bspName =
    this->GetCMakeInstance()->GetCacheDefinition("GHS_BSP_NAME");
  if (NULL == bspName)
    {
    bspName = "";
    cmSystemTools::Error("GHS_BSP_NAME cache variable must be set");
    }
  else
    {
    this->GetCMakeInstance()->MarkCliAsUsed("GHS_BSP_NAME");
    }
  std::string fBspName(this->trimQuotes(bspName));
  cmSystemTools::ReplaceString(fBspName, "\\", "/");
  this->WriteMacros();
  this->WriteHighLevelDirectives();

  GhsMultiGpj::WriteGpjTag(GhsMultiGpj::PROJECT, this->GetBuildFileStream());
  this->WriteDisclaimer(this->GetBuildFileStream());
  *this->GetBuildFileStream() << "# Top Level Project File" << std::endl;
  if (!fBspName.empty())
    {
    *this->GetBuildFileStream() << "    -bsp " << fBspName << std::endl;
    }
  this->WriteCompilerOptions(fOSDir);
}

void cmGlobalGhsMultiGenerator::CloseBuildFileStream(
  cmGeneratedFileStream **filestream)
{
  if (filestream)
    {
    delete *filestream;
    *filestream = NULL;
    }
  else
    {
    cmSystemTools::Error("Build file stream was not open.");
    }
}

void cmGlobalGhsMultiGenerator::Generate()
{
  this->cmGlobalGenerator::Generate();

  if (!this->LocalGenerators.empty())
    {
    this->OpenBuildFileStream();

    // Build all the folder build files
    for (unsigned int i = 0; i < this->LocalGenerators.size(); ++i)
      {
      cmLocalGhsMultiGenerator *lg =
        static_cast<cmLocalGhsMultiGenerator *>(this->LocalGenerators[i]);
      cmGeneratorTargetsType tgts = lg->GetMakefile()->GetGeneratorTargets();
      this->UpdateBuildFiles(&tgts);
      }
    }

  cmDeleteAll(TargetFolderBuildStreams);
  this->TargetFolderBuildStreams.clear();
}

void cmGlobalGhsMultiGenerator::GenerateBuildCommand(
  std::vector<std::string> &makeCommand, const std::string &makeProgram,
  const std::string & /*projectName*/, const std::string & /*projectDir*/,
  const std::string &targetName, const std::string & /*config*/,
  bool /*fast*/, bool /*verbose*/,
  std::vector<std::string> const &makeOptions)
{
  makeCommand.push_back(
    this->SelectMakeProgram(makeProgram, this->GetGhsBuildCommand())
    );

  makeCommand.insert(makeCommand.end(),
                     makeOptions.begin(), makeOptions.end());
  if (!targetName.empty())
    {
    if (targetName == "clean")
      {
      makeCommand.push_back("-clean");
      }
    else
      {
      makeCommand.push_back(targetName);
      }
    }
}

void cmGlobalGhsMultiGenerator::WriteMacros()
{
  char const *ghsGpjMacros =
    this->GetCMakeInstance()->GetCacheDefinition("GHS_GPJ_MACROS");
  if (NULL != ghsGpjMacros)
    {
    std::vector<std::string> expandedList;
    cmSystemTools::ExpandListArgument(std::string(ghsGpjMacros), expandedList);
    for (std::vector<std::string>::const_iterator expandedListI =
           expandedList.begin();
         expandedListI != expandedList.end(); ++expandedListI)
      {
      *this->GetBuildFileStream() << "macro " << *expandedListI << std::endl;
      }
    }
}

void cmGlobalGhsMultiGenerator::WriteHighLevelDirectives()
{
  *this->GetBuildFileStream() << "primaryTarget=arm_integrity.tgt"
                              << std::endl;
  char const *const customization =
    this->GetCMakeInstance()->GetCacheDefinition("GHS_CUSTOMIZATION");
  if (NULL != customization && strlen(customization) > 0)
    {
    *this->GetBuildFileStream() << "customization="
                                << trimQuotes(customization)
                                << std::endl;
    this->GetCMakeInstance()->MarkCliAsUsed("GHS_CUSTOMIZATION");
    }
}

void cmGlobalGhsMultiGenerator::WriteCompilerOptions(std::string const &fOSDir)
{
  *this->GetBuildFileStream() << "    -os_dir=\"" << fOSDir << "\""
                              << std::endl;
}

void cmGlobalGhsMultiGenerator::WriteDisclaimer(std::ostream *os)
{
  (*os) << "#" << std::endl
        << "# CMAKE generated file: DO NOT EDIT!" << std::endl
        << "# Generated by \"" << GetActualName() << "\""
        << " Generator, CMake Version " << cmVersion::GetMajorVersion() << "."
        << cmVersion::GetMinorVersion() << std::endl
        << "#" << std::endl;
}

void cmGlobalGhsMultiGenerator::AddFilesUpToPath(
  cmGeneratedFileStream *mainBuildFile,
  std::map<std::string, cmGeneratedFileStream *> *targetFolderBuildStreams,
  char const *homeOutputDirectory, std::string const &path,
  GhsMultiGpj::Types projType, std::string const &relPath)
{
  std::string workingPath(path);
  cmSystemTools::ConvertToUnixSlashes(workingPath);
  std::vector<cmsys::String> splitPath =
    cmSystemTools::SplitString(workingPath);
  std::string workingRelPath(relPath);
  cmSystemTools::ConvertToUnixSlashes(workingRelPath);
  if (!workingRelPath.empty())
    {
    workingRelPath += "/";
    }
  std::string pathUpTo;
  for (std::vector<cmsys::String>::const_iterator splitPathI =
         splitPath.begin();
       splitPath.end() != splitPathI; ++splitPathI)
    {
    pathUpTo += *splitPathI;
    if (targetFolderBuildStreams->end() ==
        targetFolderBuildStreams->find(pathUpTo))
      {
      AddFilesUpToPathNewBuildFile(
        mainBuildFile, targetFolderBuildStreams, homeOutputDirectory,
        pathUpTo, splitPath.begin() == splitPathI, workingRelPath, projType);
      }
    AddFilesUpToPathAppendNextFile(targetFolderBuildStreams, pathUpTo,
                                   splitPathI, splitPath.end(), projType);
    pathUpTo += "/";
    }
}

void cmGlobalGhsMultiGenerator::Open(
  std::string const &mapKeyName, std::string const &fileName,
  std::map<std::string, cmGeneratedFileStream *> *fileMap)
{
  if (fileMap->end() == fileMap->find(fileName))
    {
    cmGeneratedFileStream *temp(new cmGeneratedFileStream);
    temp->open(fileName.c_str());
    (*fileMap)[mapKeyName] = temp;
    }
}

void cmGlobalGhsMultiGenerator::AddFilesUpToPathNewBuildFile(
  cmGeneratedFileStream *mainBuildFile,
  std::map<std::string, cmGeneratedFileStream *> *targetFolderBuildStreams,
  char const *homeOutputDirectory, std::string const &pathUpTo,
  bool const isFirst, std::string const &relPath,
  GhsMultiGpj::Types const projType)
{
  // create folders up to file path
  std::string absPath = std::string(homeOutputDirectory) + "/" + relPath;
  std::string newPath = absPath + pathUpTo;
  if (!cmSystemTools::FileExists(newPath.c_str()))
    {
    cmSystemTools::MakeDirectory(newPath.c_str());
    }

  // Write out to filename for first time
  std::string relFilename(GetFileNameFromPath(pathUpTo));
  std::string absFilename = absPath + relFilename;
  Open(pathUpTo, absFilename, targetFolderBuildStreams);
  OpenBuildFileStream((*targetFolderBuildStreams)[pathUpTo]);
  GhsMultiGpj::WriteGpjTag(projType, (*targetFolderBuildStreams)[pathUpTo]);
  WriteDisclaimer((*targetFolderBuildStreams)[pathUpTo]);

  // Add to main build file
  if (isFirst)
    {
    *mainBuildFile << relFilename << " ";
    GhsMultiGpj::WriteGpjTag(projType, mainBuildFile);
    }
}

void cmGlobalGhsMultiGenerator::AddFilesUpToPathAppendNextFile(
  std::map<std::string, cmGeneratedFileStream *> *targetFolderBuildStreams,
  std::string const &pathUpTo,
  std::vector<cmsys::String>::const_iterator splitPathI,
  std::vector<cmsys::String>::const_iterator end,
  GhsMultiGpj::Types const projType)
{
  std::vector<cmsys::String>::const_iterator splitPathNextI = splitPathI + 1;
  if (end != splitPathNextI &&
      targetFolderBuildStreams->end() ==
      targetFolderBuildStreams->find(pathUpTo + "/" + *splitPathNextI))
    {
    std::string nextFilename(*splitPathNextI);
    nextFilename = GetFileNameFromPath(nextFilename);
    *(*targetFolderBuildStreams)[pathUpTo] << nextFilename << " ";
    GhsMultiGpj::WriteGpjTag(projType, (*targetFolderBuildStreams)[pathUpTo]);
    }
}

std::string
cmGlobalGhsMultiGenerator::GetFileNameFromPath(std::string const &path)
{
  std::string output(path);
  if (!path.empty())
    {
    cmSystemTools::ConvertToUnixSlashes(output);
    std::vector<cmsys::String> splitPath = cmSystemTools::SplitString(output);
    output += "/" + splitPath.back() + FILE_EXTENSION;
    }
  return output;
}

void cmGlobalGhsMultiGenerator::UpdateBuildFiles(
  cmGeneratorTargetsType *tgts)
{
  for (cmGeneratorTargetsType::iterator tgtsI = tgts->begin();
       tgtsI != tgts->end(); ++tgtsI)
    {
    const cmTarget *tgt(tgtsI->first);
    if (IsTgtForBuild(tgt))
      {
      char const *rawFolderName = tgtsI->first->GetProperty("FOLDER");
      if (NULL == rawFolderName)
        {
        rawFolderName = "";
        }
      std::string folderName(rawFolderName);
      if (this->TargetFolderBuildStreams.end() ==
          this->TargetFolderBuildStreams.find(folderName))
        {
        this->AddFilesUpToPath(
          GetBuildFileStream(), &this->TargetFolderBuildStreams,
          this->GetCMakeInstance()->GetHomeOutputDirectory(), folderName,
          GhsMultiGpj::PROJECT);
        }
      std::vector<cmsys::String> splitPath = cmSystemTools::SplitString(
            cmGhsMultiTargetGenerator::GetRelBuildFileName(tgt));
      std::string foldNameRelBuildFile(*(splitPath.end() - 2) + "/" +
                                       splitPath.back());
      *this->TargetFolderBuildStreams[folderName] << foldNameRelBuildFile
                                                  << " ";
      GhsMultiGpj::WriteGpjTag(cmGhsMultiTargetGenerator::GetGpjTag(tgt),
                               this->TargetFolderBuildStreams[folderName]);
      }
    }
}

bool cmGlobalGhsMultiGenerator::IsTgtForBuild(const cmTarget *tgt)
{
  const std::string config =
    tgt->GetMakefile()->GetSafeDefinition("CMAKE_BUILD_TYPE");
  std::vector<cmSourceFile *> tgtSources;
  tgt->GetSourceFiles(tgtSources, config);
  bool tgtInBuild = true;
  char const *excludeFromAll = tgt->GetProperty("EXCLUDE_FROM_ALL");
  if (NULL != excludeFromAll && '1' == excludeFromAll[0] &&
    '\0' == excludeFromAll[1])
  {
    tgtInBuild = false;
  }
  return !tgtSources.empty() && tgtInBuild;
}

std::string cmGlobalGhsMultiGenerator::trimQuotes(std::string const &str)
{
  std::string result;
  result.reserve(str.size());
  for (const char *ch = str.c_str(); *ch != '\0'; ++ch)
    {
    if (*ch != '"')
      {
      result += *ch;
      }
    }
  return result;
}
