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

#include "cmComputeLinkInformation.h"
#include "cmGeneratedFileStream.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGhsMultiGenerator.h"
#include "cmLinkLineComputer.h"
#include "cmLocalGhsMultiGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"
#include "cmSourceGroup.h"
#include "cmTarget.h"

cmGhsMultiTargetGenerator::cmGhsMultiTargetGenerator(cmGeneratorTarget* target)
  : GeneratorTarget(target)
  , LocalGenerator(
      static_cast<cmLocalGhsMultiGenerator*>(target->GetLocalGenerator()))
  , Makefile(target->Target->GetMakefile())
  , Name(target->GetName())
{
  // Store the configuration name that is being used
  if (const char* config = this->Makefile->GetDefinition("CMAKE_BUILD_TYPE")) {
    // Use the build type given by the user.
    this->ConfigName = config;
  } else {
    // No configuration type given.
    this->ConfigName.clear();
  }
}

cmGhsMultiTargetGenerator::~cmGhsMultiTargetGenerator()
{
}

void cmGhsMultiTargetGenerator::Generate()
{
  // Determine type of target for this project
  switch (this->GeneratorTarget->GetType()) {
    case cmStateEnums::EXECUTABLE: {
      // Get the name of the executable to generate.
      this->TargetNameReal =
        this->GeneratorTarget->GetExecutableNames(this->ConfigName).Real;
      if (cmGhsMultiTargetGenerator::DetermineIfIntegrityApp()) {
        this->TagType = GhsMultiGpj::INTERGRITY_APPLICATION;
      } else {
        this->TagType = GhsMultiGpj::PROGRAM;
      }
      break;
    }
    case cmStateEnums::STATIC_LIBRARY: {
      this->TargetNameReal =
        this->GeneratorTarget->GetLibraryNames(this->ConfigName).Real;
      this->TagType = GhsMultiGpj::LIBRARY;
      break;
    }
    case cmStateEnums::SHARED_LIBRARY: {
      std::string msg = "add_library(<name> SHARED ...) not supported: ";
      msg += this->Name;
      cmSystemTools::Message(msg);
      return;
    }
    case cmStateEnums::OBJECT_LIBRARY: {
      this->TargetNameReal =
        this->GeneratorTarget->GetLibraryNames(this->ConfigName).Real;
      this->TagType = GhsMultiGpj::SUBPROJECT;
      break;
    }
    case cmStateEnums::MODULE_LIBRARY: {
      std::string msg = "add_library(<name> MODULE ...) not supported: ";
      msg += this->Name;
      cmSystemTools::Message(msg);
      return;
    }
    case cmStateEnums::UTILITY: {
      std::string msg = "add_custom_target(<name> ...) not supported: ";
      msg += this->Name;
      cmSystemTools::Message(msg);
      return;
    }
    default:
      return;
  }

  // Tell the global generator the name of the project file
  this->GeneratorTarget->Target->SetProperty("GENERATOR_FILE_NAME",
                                             this->Name.c_str());
  this->GeneratorTarget->Target->SetProperty(
    "GENERATOR_FILE_NAME_EXT", GhsMultiGpj::GetGpjTag(this->TagType));

  this->GenerateTarget();
}

void cmGhsMultiTargetGenerator::GenerateTarget()
{
  // Open the filestream in copy-if-different mode.
  std::string fname = this->LocalGenerator->GetCurrentBinaryDirectory();
  fname += "/";
  fname += this->Name;
  fname += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
  cmGeneratedFileStream fout(fname.c_str());
  fout.SetCopyIfDifferent(true);

  this->GetGlobalGenerator()->WriteFileHeader(fout);
  GhsMultiGpj::WriteGpjTag(this->TagType, fout);

  const std::string language(
    this->GeneratorTarget->GetLinkerLanguage(this->ConfigName));

  this->WriteTargetSpecifics(fout, this->ConfigName);
  this->SetCompilerFlags(this->ConfigName, language);
  this->WriteCompilerFlags(fout, this->ConfigName, language);
  this->WriteCompilerDefinitions(fout, this->ConfigName, language);
  this->WriteIncludes(fout, this->ConfigName, language);
  this->WriteTargetLinkLine(fout, this->ConfigName);
  this->WriteCustomCommands(fout);
  this->WriteSources(fout);
  this->WriteReferences(fout);
  fout.Close();
}

cmGlobalGhsMultiGenerator* cmGhsMultiTargetGenerator::GetGlobalGenerator()
  const
{
  return static_cast<cmGlobalGhsMultiGenerator*>(
    this->LocalGenerator->GetGlobalGenerator());
}

void cmGhsMultiTargetGenerator::WriteTargetSpecifics(std::ostream& fout,
                                                     const std::string& config)
{
  std::string outpath;
  std::string rootpath = this->LocalGenerator->GetCurrentBinaryDirectory();

  if (this->TagType != GhsMultiGpj::SUBPROJECT) {
    // set target binary file destination
    outpath = this->GeneratorTarget->GetDirectory(config);
    outpath =
      this->LocalGenerator->MaybeConvertToRelativePath(rootpath, outpath);
    fout << "    :binDirRelative=\"" << outpath << "\"" << std::endl;
    fout << "    -o \"" << this->TargetNameReal << "\"" << std::endl;
  }

  // set target object file destination
  outpath = this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
  fout << "    :outputDirRelative=\"" << outpath << "\"" << std::endl;
}

void cmGhsMultiTargetGenerator::SetCompilerFlags(std::string const& config,
                                                 const std::string& language)
{
  std::map<std::string, std::string>::iterator i =
    this->FlagsByLanguage.find(language);
  if (i == this->FlagsByLanguage.end()) {
    std::string flags;
    const char* lang = language.c_str();

    this->LocalGenerator->AddLanguageFlags(flags, this->GeneratorTarget, lang,
                                           config);

    this->LocalGenerator->AddCMP0018Flags(flags, this->GeneratorTarget, lang,
                                          config);
    this->LocalGenerator->AddVisibilityPresetFlags(
      flags, this->GeneratorTarget, lang);

    // Append old-style preprocessor definition flags.
    if (this->Makefile->GetDefineFlags() != " ") {
      this->LocalGenerator->AppendFlags(flags,
                                        this->Makefile->GetDefineFlags());
    }

    // Add target-specific flags.
    this->LocalGenerator->AddCompileOptions(flags, this->GeneratorTarget, lang,
                                            config);

    std::map<std::string, std::string>::value_type entry(language, flags);
    i = this->FlagsByLanguage.insert(entry).first;
  }
}

std::string cmGhsMultiTargetGenerator::GetDefines(const std::string& language,
                                                  std::string const& config)
{
  std::map<std::string, std::string>::iterator i =
    this->DefinesByLanguage.find(language);
  if (i == this->DefinesByLanguage.end()) {
    std::set<std::string> defines;
    const char* lang = language.c_str();
    // Add preprocessor definitions for this target and configuration.
    this->LocalGenerator->GetTargetDefines(this->GeneratorTarget, config,
                                           language, defines);

    std::string definesString;
    this->LocalGenerator->JoinDefines(defines, definesString, lang);

    std::map<std::string, std::string>::value_type entry(language,
                                                         definesString);
    i = this->DefinesByLanguage.insert(entry).first;
  }
  return i->second;
}

void cmGhsMultiTargetGenerator::WriteCompilerFlags(std::ostream& fout,
                                                   std::string const&,
                                                   const std::string& language)
{
  std::map<std::string, std::string>::iterator flagsByLangI =
    this->FlagsByLanguage.find(language);
  if (flagsByLangI != this->FlagsByLanguage.end()) {
    if (!flagsByLangI->second.empty()) {
      std::vector<std::string> ghsCompFlags =
        cmSystemTools::ParseArguments(flagsByLangI->second.c_str());
      for (auto& f : ghsCompFlags) {
        fout << "    " << f << std::endl;
      }
    }
  }
}

void cmGhsMultiTargetGenerator::WriteCompilerDefinitions(
  std::ostream& fout, const std::string& config, const std::string& language)
{
  std::vector<std::string> compileDefinitions;
  this->GeneratorTarget->GetCompileDefinitions(compileDefinitions, config,
                                               language);
  for (std::string const& compileDefinition : compileDefinitions) {
    fout << "    -D" << compileDefinition << std::endl;
  }
}

void cmGhsMultiTargetGenerator::WriteIncludes(std::ostream& fout,
                                              const std::string& config,
                                              const std::string& language)
{
  std::vector<std::string> includes;
  this->LocalGenerator->GetIncludeDirectories(includes, this->GeneratorTarget,
                                              language, config);

  for (std::string const& include : includes) {
    fout << "    -I\"" << include << "\"" << std::endl;
  }
}

void cmGhsMultiTargetGenerator::WriteTargetLinkLine(std::ostream& fout,
                                                    std::string const& config)
{
  if (this->TagType == GhsMultiGpj::INTERGRITY_APPLICATION) {
    return;
  }

  std::string linkLibraries;
  std::string flags;
  std::string linkFlags;
  std::string frameworkPath;
  std::string linkPath;

  std::unique_ptr<cmLinkLineComputer> linkLineComputer(
    this->GetGlobalGenerator()->CreateLinkLineComputer(
      this->LocalGenerator,
      this->LocalGenerator->GetStateSnapshot().GetDirectory()));

  this->LocalGenerator->GetTargetFlags(
    linkLineComputer.get(), config, linkLibraries, flags, linkFlags,
    frameworkPath, linkPath, this->GeneratorTarget);

  // write out link options
  std::vector<std::string> lopts =
    cmSystemTools::ParseArguments(linkFlags.c_str());
  for (auto& l : lopts) {
    fout << "    " << l << std::endl;
  }

  // write out link search paths
  // must be quoted for paths that contain spaces
  std::vector<std::string> lpath =
    cmSystemTools::ParseArguments(linkPath.c_str());
  for (auto& l : lpath) {
    fout << "    -L\"" << l << "\"" << std::endl;
  }

  // write out link libs
  // must be quoted for filepaths that contains spaces
  std::string cbd = this->LocalGenerator->GetCurrentBinaryDirectory();

  std::vector<std::string> llibs =
    cmSystemTools::ParseArguments(linkLibraries.c_str());
  for (auto& l : llibs) {
    if (l.compare(0, 2, "-l") == 0) {
      fout << "    \"" << l << "\"" << std::endl;
    } else {
      std::string rl = cmSystemTools::CollapseCombinedPath(cbd, l);
      fout << "    -l\"" << rl << "\"" << std::endl;
    }
  }
}

void cmGhsMultiTargetGenerator::WriteCustomCommands(std::ostream& fout)
{
  WriteCustomCommandsHelper(fout, this->GeneratorTarget->GetPreBuildCommands(),
                            cmTarget::PRE_BUILD);
  WriteCustomCommandsHelper(
    fout, this->GeneratorTarget->GetPostBuildCommands(), cmTarget::POST_BUILD);
}

void cmGhsMultiTargetGenerator::WriteCustomCommandsHelper(
  std::ostream& fout, std::vector<cmCustomCommand> const& commandsSet,
  cmTarget::CustomCommandType const commandType)
{
  for (cmCustomCommand const& customCommand : commandsSet) {
    cmCustomCommandLines const& commandLines = customCommand.GetCommandLines();
    for (cmCustomCommandLine const& command : commandLines) {
      switch (commandType) {
        case cmTarget::PRE_BUILD:
          fout << "    :preexecShellSafe=";
          break;
        case cmTarget::POST_BUILD:
          fout << "    :postexecShellSafe=";
          break;
        default:
          assert("Only pre and post are supported");
      }

      bool firstIteration = true;
      for (std::string const& commandLine : command) {
        std::string subCommandE =
          this->LocalGenerator->EscapeForShell(commandLine, true);
        fout << (firstIteration ? "'" : " ");
        // Need to double escape backslashes
        cmSystemTools::ReplaceString(subCommandE, "\\", "\\\\");
        fout << subCommandE;
        firstIteration = false;
      }
      if (!command.empty()) {
        fout << "'" << std::endl;
      }
    }
  }
}

void cmGhsMultiTargetGenerator::WriteSourceProperty(std::ostream& fout,
                                                    const cmSourceFile* sf,
                                                    std::string propName,
                                                    std::string propFlag)
{
  const char* prop = sf->GetProperty(propName);
  if (prop) {
    std::vector<std::string> list;
    cmSystemTools::ExpandListArgument(prop, list);
    for (auto& p : list) {
      fout << "    " << propFlag << p << std::endl;
    }
  }
}

void cmGhsMultiTargetGenerator::WriteSources(std::ostream& fout_proj)
{
  /* vector of all sources for this target */
  std::vector<cmSourceFile*> sources;
  this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName);

  /* vector of all groups defined for this target
   * -- but the vector is not expanded with sub groups or in any useful order
   */
  std::vector<cmSourceGroup> sourceGroups = this->Makefile->GetSourceGroups();

  /* for each source file assign it to its group */
  std::map<std::string, std::vector<cmSourceFile*>> groupFiles;
  std::set<std::string> groupNames;
  for (auto& sf : sources) {
    cmSourceGroup* sourceGroup =
      this->Makefile->FindSourceGroup(sf->GetFullPath(), sourceGroups);
    std::string gn = sourceGroup->GetFullName();
    groupFiles[gn].push_back(sf);
    groupNames.insert(gn);
  }

  /* list of known groups and the order they are displayed in a project file */
  const std::vector<std::string> standardGroups = {
    "Header Files", "Source Files",     "CMake Rules",
    "Object Files", "Object Libraries", "Resources"
  };

  /* list of groups in the order they are displayed in a project file*/
  std::vector<std::string> groupFilesList(groupFiles.size());

  /* put the groups in the order they should be listed
   * - standard groups first, and then everything else
   *   in the order used by std::map.
   */
  int i = 0;
  for (const std::string& gn : standardGroups) {
    auto n = groupNames.find(gn);
    if (n != groupNames.end()) {
      groupFilesList[i] = *n;
      i += 1;
      groupNames.erase(gn);
    }
  }

  { /* catch-all group - is last item */
    std::string gn = "";
    auto n = groupNames.find(gn);
    if (n != groupNames.end()) {
      groupFilesList.back() = *n;
      groupNames.erase(gn);
    }
  }

  for (auto& n : groupNames) {
    groupFilesList[i] = n;
    i += 1;
  }

  /* sort the files within each group */
  for (auto& n : groupFilesList) {
    std::sort(groupFiles[n].begin(), groupFiles[n].end(),
              [](cmSourceFile* l, cmSourceFile* r) {
                return l->GetFullPath() < r->GetFullPath();
              });
  }

  /* list of open project files */
  std::vector<cmGeneratedFileStream*> gfiles;

  /* write files into the proper project file
   * -- groups go into main project file
   *    unless FOLDER property or variable is set.
   */
  for (auto& sg : groupFilesList) {
    std::ostream* fout;
    bool useProjectFile =
      cmSystemTools::IsOn(
        this->GeneratorTarget->GetProperty("GHS_NO_SOURCE_GROUP_FILE")) ||
      cmSystemTools::IsOn(
        this->Makefile->GetDefinition("CMAKE_GHS_NO_SOURCE_GROUP_FILE"));
    if (useProjectFile || sg.empty()) {
      fout = &fout_proj;
    } else {
      // Open the filestream in copy-if-different mode.
      std::string gname = sg;
      cmsys::SystemTools::ReplaceString(gname, "\\", "_");
      std::string lpath =
        this->LocalGenerator->GetTargetDirectory(this->GeneratorTarget);
      lpath += "/";
      lpath += gname;
      lpath += cmGlobalGhsMultiGenerator::FILE_EXTENSION;
      std::string fpath = this->LocalGenerator->GetCurrentBinaryDirectory();
      fpath += "/";
      fpath += lpath;
      cmGeneratedFileStream* f = new cmGeneratedFileStream(fpath.c_str());
      f->SetCopyIfDifferent(true);
      gfiles.push_back(f);
      fout = f;
      this->GetGlobalGenerator()->WriteFileHeader(*f);
      GhsMultiGpj::WriteGpjTag(GhsMultiGpj::SUBPROJECT, *f);
      fout_proj << lpath << " ";
      GhsMultiGpj::WriteGpjTag(GhsMultiGpj::SUBPROJECT, fout_proj);
    }

    if (useProjectFile) {
      if (sg.empty()) {
        *fout << "{comment} Others" << std::endl;
      } else {
        *fout << "{comment} " << sg << std::endl;
      }
    }

    /* output rule for each source file */
    for (const cmSourceFile* si : groupFiles[sg]) {

      // Convert filename to native system
      // WORKAROUND: GHS MULTI 6.1.4 and 6.1.6 are known to need backslash on
      // windows when opening some files from the search window.
      std::string fname(si->GetFullPath());
      cmSystemTools::ConvertToOutputSlashes(fname);
      *fout << fname << std::endl;

      if ("ld" != si->GetExtension() && "int" != si->GetExtension() &&
          "bsp" != si->GetExtension()) {
        this->WriteObjectLangOverride(*fout, si);
      }

      this->WriteSourceProperty(*fout, si, "INCLUDE_DIRECTORIES", "-I");
      this->WriteSourceProperty(*fout, si, "COMPILE_DEFINITIONS", "-D");
      this->WriteSourceProperty(*fout, si, "COMPILE_OPTIONS", "");

      /* to avoid clutter in the gui only print out the objectName if it has
       * been renamed */
      std::string objectName = this->GeneratorTarget->GetObjectName(si);
      if (!objectName.empty() &&
          this->GeneratorTarget->HasExplicitObjectName(si)) {
        *fout << "    -o " << objectName << std::endl;
      }
    }
  }

  for (cmGeneratedFileStream* f : gfiles) {
    f->Close();
  }
}

void cmGhsMultiTargetGenerator::WriteObjectLangOverride(
  std::ostream& fout, const cmSourceFile* sourceFile)
{
  const char* rawLangProp = sourceFile->GetProperty("LANGUAGE");
  if (NULL != rawLangProp) {
    std::string sourceLangProp(rawLangProp);
    std::string extension(sourceFile->GetExtension());
    if ("CXX" == sourceLangProp && ("c" == extension || "C" == extension)) {
      fout << "    -dotciscxx" << std::endl;
    }
  }
}

void cmGhsMultiTargetGenerator::WriteReferences(std::ostream& fout)
{
  // This only applies to INTEGRITY Applications
  if (this->TagType != GhsMultiGpj::INTERGRITY_APPLICATION) {
    return;
  }

  // Get the targets that this one depends upon
  cmTargetDependSet unordered =
    this->GetGlobalGenerator()->GetTargetDirectDepends(this->GeneratorTarget);
  cmGlobalGhsMultiGenerator::OrderedTargetDependSet ordered(unordered,
                                                            this->Name);
  for (auto& t : ordered) {
    std::string tname = t->GetName();
    std::string tpath = t->LocalGenerator->GetCurrentBinaryDirectory();
    std::string rootpath = this->LocalGenerator->GetCurrentBinaryDirectory();
    std::string outpath =
      this->LocalGenerator->MaybeConvertToRelativePath(rootpath, tpath) + "/" +
      tname + "REF" + cmGlobalGhsMultiGenerator::FILE_EXTENSION;

    fout << outpath;
    fout << "    ";
    GhsMultiGpj::WriteGpjTag(GhsMultiGpj::REFERENCE, fout);

    // Tell the global generator that a refernce project needs to be created
    t->Target->SetProperty("GHS_REFERENCE_PROJECT", "ON");
  }
}

bool cmGhsMultiTargetGenerator::DetermineIfIntegrityApp(void)
{
  const char* p = this->GeneratorTarget->GetProperty("ghs_integrity_app");
  if (p) {
    return cmSystemTools::IsOn(
      this->GeneratorTarget->GetProperty("ghs_integrity_app"));
  } else {
    std::vector<cmSourceFile*> sources;
    this->GeneratorTarget->GetSourceFiles(sources, this->ConfigName);
    for (auto& sf : sources) {
      if ("int" == sf->GetExtension()) {
        return true;
      }
    }
    return false;
  }
}
