/*============================================================================
  CMake - Cross Platform Makefile Generator
  Copyright 2004-2011 Kitware, Inc.
  Copyright 2011 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 "cmQtAutoGeneratorInitializer.h"

#include "cmLocalGenerator.h"
#include "cmMakefile.h"
#include "cmSourceFile.h"

#include <sys/stat.h>

#include <cmsys/FStream.hxx>

#if defined(_WIN32) && !defined(__CYGWIN__)
# include "cmGlobalVisualStudioGenerator.h"
#endif

static void SetupSourceFiles(cmGeneratorTarget const* target,
                                   std::vector<std::string>& skipMoc,
                                   std::vector<std::string>& mocSources,
                                   std::vector<std::string>& mocHeaders,
                                   std::vector<std::string>& skipUic)
{
  cmMakefile* makefile = target->Target->GetMakefile();

  std::vector<cmSourceFile*> srcFiles;
  target->GetConfigCommonSourceFiles(srcFiles);

  std::vector<std::string> newRccFiles;

  for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
      fileIt != srcFiles.end();
      ++fileIt)
    {
    cmSourceFile* sf = *fileIt;
    std::string absFile = cmsys::SystemTools::GetRealPath(
                                                    sf->GetFullPath());
    bool skipFileForMoc =
        cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOMOC"));
    bool generated = cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED"));

    if(cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTOUIC")))
      {
      skipUic.push_back(absFile);
      }

    std::string ext = sf->GetExtension();

    if (target->GetPropertyAsBool("AUTORCC"))
      {
      if (ext == "qrc"
          && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")))
        {
        std::string basename = cmsys::SystemTools::
                                      GetFilenameWithoutLastExtension(absFile);

        std::string rcc_output_dir = target->GetSupportDirectory();
        cmSystemTools::MakeDirectory(rcc_output_dir.c_str());
        std::string rcc_output_file = rcc_output_dir;
        rcc_output_file += "/qrc_" + basename + ".cpp";
        makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
                                rcc_output_file.c_str(), false);
        makefile->GetOrCreateSource(rcc_output_file, true);
        newRccFiles.push_back(rcc_output_file);
        }
      }

    if (!generated)
      {
      if (skipFileForMoc)
        {
        skipMoc.push_back(absFile);
        }
      else
        {
        cmSystemTools::FileFormat fileType = cmSystemTools::GetFileFormat(
                                                                ext.c_str());
        if (fileType == cmSystemTools::CXX_FILE_FORMAT)
          {
          mocSources.push_back(absFile);
          }
        else if (fileType == cmSystemTools::HEADER_FILE_FORMAT)
          {
          mocHeaders.push_back(absFile);
          }
        }
      }
    }

  for(std::vector<std::string>::const_iterator fileIt = newRccFiles.begin();
      fileIt != newRccFiles.end();
      ++fileIt)
    {
    const_cast<cmGeneratorTarget*>(target)->AddSource(*fileIt);
    }
}

static void GetCompileDefinitionsAndDirectories(
  cmGeneratorTarget const* target,
  const std::string& config,
  std::string &incs,
  std::string &defs)
{
  std::vector<std::string> includeDirs;
  cmLocalGenerator *localGen = target->GetLocalGenerator();
  // Get the include dirs for this target, without stripping the implicit
  // include dirs off, see http://public.kitware.com/Bug/view.php?id=13667
  localGen->GetIncludeDirectories(includeDirs, target, "CXX", config, false);

  incs = cmJoin(includeDirs, ";");

  std::set<std::string> defines;
  localGen->AddCompileDefinitions(defines, target, config, "CXX");

  defs += cmJoin(defines, ";");
}

static void SetupAutoMocTarget(cmGeneratorTarget const* target,
                          const std::string &autogenTargetName,
                          std::vector<std::string> const& skipMoc,
                          std::vector<std::string> const& mocHeaders,
                          std::map<std::string, std::string> &configIncludes,
                          std::map<std::string, std::string> &configDefines)
{
  cmLocalGenerator* lg = target->GetLocalGenerator();
  cmMakefile* makefile = target->Target->GetMakefile();

  const char* tmp = target->GetProperty("AUTOMOC_MOC_OPTIONS");
  std::string _moc_options = (tmp!=0 ? tmp : "");
  makefile->AddDefinition("_moc_options",
          cmOutputConverter::EscapeForCMake(_moc_options).c_str());
  makefile->AddDefinition("_skip_moc",
          cmOutputConverter::EscapeForCMake(cmJoin(skipMoc, ";")).c_str());
  makefile->AddDefinition("_moc_headers",
          cmOutputConverter::EscapeForCMake(cmJoin(mocHeaders, ";")).c_str());
  bool relaxedMode = makefile->IsOn("CMAKE_AUTOMOC_RELAXED_MODE");
  makefile->AddDefinition("_moc_relaxed_mode", relaxedMode ? "TRUE" : "FALSE");

  std::string _moc_incs;
  std::string _moc_compile_defs;
  std::vector<std::string> configs;
  const std::string& config = makefile->GetConfigurations(configs);
  GetCompileDefinitionsAndDirectories(target, config,
                                      _moc_incs, _moc_compile_defs);

  makefile->AddDefinition("_moc_incs",
          cmOutputConverter::EscapeForCMake(_moc_incs).c_str());
  makefile->AddDefinition("_moc_compile_defs",
          cmOutputConverter::EscapeForCMake(_moc_compile_defs).c_str());

  for (std::vector<std::string>::const_iterator li = configs.begin();
       li != configs.end(); ++li)
    {
    std::string config_moc_incs;
    std::string config_moc_compile_defs;
    GetCompileDefinitionsAndDirectories(target, *li,
                                        config_moc_incs,
                                        config_moc_compile_defs);
    if (config_moc_incs != _moc_incs)
      {
      configIncludes[*li] =
                    cmOutputConverter::EscapeForCMake(config_moc_incs);
      if(_moc_incs.empty())
        {
        _moc_incs = config_moc_incs;
        }
      }
    if (config_moc_compile_defs != _moc_compile_defs)
      {
      configDefines[*li] =
            cmOutputConverter::EscapeForCMake(config_moc_compile_defs);
      if(_moc_compile_defs.empty())
        {
        _moc_compile_defs = config_moc_compile_defs;
        }
      }
    }

  const char *qtVersion = makefile->GetDefinition("_target_qt_version");
  if (strcmp(qtVersion, "5") == 0)
    {
    cmGeneratorTarget *qt5Moc =
        lg->FindGeneratorTargetToUse("Qt5::moc");
    if (!qt5Moc)
      {
      cmSystemTools::Error("Qt5::moc target not found ",
                          autogenTargetName.c_str());
      return;
      }
    makefile->AddDefinition("_qt_moc_executable",
                            qt5Moc->ImportedGetLocation(""));
    }
  else if (strcmp(qtVersion, "4") == 0)
    {
    cmGeneratorTarget *qt4Moc =
        lg->FindGeneratorTargetToUse("Qt4::moc");
    if (!qt4Moc)
      {
      cmSystemTools::Error("Qt4::moc target not found ",
                          autogenTargetName.c_str());
      return;
      }
    makefile->AddDefinition("_qt_moc_executable",
                            qt4Moc->ImportedGetLocation(""));
    }
  else
    {
    cmSystemTools::Error("The CMAKE_AUTOMOC feature supports only Qt 4 and "
                        "Qt 5 ", autogenTargetName.c_str());
    }
}

static void GetUicOpts(cmGeneratorTarget const* target,
                       const std::string& config,
                       std::string &optString)
{
  std::vector<std::string> opts;
  target->GetAutoUicOptions(opts, config);
  optString = cmJoin(opts, ";");
}

static void SetupAutoUicTarget(cmGeneratorTarget const* target,
                          std::vector<std::string> const& skipUic,
                          std::map<std::string, std::string> &configUicOptions)
{
  cmLocalGenerator* lg = target->GetLocalGenerator();
  cmMakefile *makefile = target->Target->GetMakefile();

  std::set<std::string> skipped;
  skipped.insert(skipUic.begin(), skipUic.end());

  makefile->AddDefinition("_skip_uic",
          cmOutputConverter::EscapeForCMake(cmJoin(skipUic, ";")).c_str());

  std::vector<cmSourceFile*> uiFilesWithOptions
                                        = makefile->GetQtUiFilesWithOptions();

  const char *qtVersion = makefile->GetDefinition("_target_qt_version");

  std::string _uic_opts;
  std::vector<std::string> configs;
  const std::string& config = makefile->GetConfigurations(configs);
  GetUicOpts(target, config, _uic_opts);

  if (!_uic_opts.empty())
    {
    _uic_opts = cmOutputConverter::EscapeForCMake(_uic_opts);
    makefile->AddDefinition("_uic_target_options", _uic_opts.c_str());
    }
  for (std::vector<std::string>::const_iterator li = configs.begin();
       li != configs.end(); ++li)
    {
    std::string config_uic_opts;
    GetUicOpts(target, *li, config_uic_opts);
    if (config_uic_opts != _uic_opts)
      {
      configUicOptions[*li] =
                    cmOutputConverter::EscapeForCMake(config_uic_opts);
      if(_uic_opts.empty())
        {
        _uic_opts = config_uic_opts;
        }
      }
    }

  std::string uiFileFiles;
  std::string uiFileOptions;
  const char* sep = "";

  for(std::vector<cmSourceFile*>::const_iterator fileIt =
      uiFilesWithOptions.begin();
      fileIt != uiFilesWithOptions.end();
      ++fileIt)
    {
    cmSourceFile* sf = *fileIt;
    std::string absFile = cmsys::SystemTools::GetRealPath(
                                                    sf->GetFullPath());

    if (!skipped.insert(absFile).second)
      {
      continue;
      }
    uiFileFiles += sep;
    uiFileFiles += absFile;
    uiFileOptions += sep;
    std::string opts = sf->GetProperty("AUTOUIC_OPTIONS");
    cmSystemTools::ReplaceString(opts, ";", "@list_sep@");
    uiFileOptions += opts;
    sep = ";";
    }

  makefile->AddDefinition("_qt_uic_options_files",
              cmOutputConverter::EscapeForCMake(uiFileFiles).c_str());
  makefile->AddDefinition("_qt_uic_options_options",
            cmOutputConverter::EscapeForCMake(uiFileOptions).c_str());

  std::string targetName = target->GetName();
  if (strcmp(qtVersion, "5") == 0)
    {
    cmGeneratorTarget *qt5Uic =
        lg->FindGeneratorTargetToUse("Qt5::uic");
    if (!qt5Uic)
      {
      // Project does not use Qt5Widgets, but has AUTOUIC ON anyway
      }
    else
      {
      makefile->AddDefinition("_qt_uic_executable",
                              qt5Uic->ImportedGetLocation(""));
      }
    }
  else if (strcmp(qtVersion, "4") == 0)
    {
    cmGeneratorTarget *qt4Uic =
        lg->FindGeneratorTargetToUse("Qt4::uic");
    if (!qt4Uic)
      {
      cmSystemTools::Error("Qt4::uic target not found ",
                          targetName.c_str());
      return;
      }
    makefile->AddDefinition("_qt_uic_executable",
                            qt4Uic->ImportedGetLocation(""));
    }
  else
    {
    cmSystemTools::Error("The CMAKE_AUTOUIC feature supports only Qt 4 and "
                        "Qt 5 ", targetName.c_str());
    }
}

static std::string GetRccExecutable(cmGeneratorTarget const* target)
{
  cmLocalGenerator* lg = target->GetLocalGenerator();
  cmMakefile *makefile = target->Target->GetMakefile();
  const char *qtVersion = makefile->GetDefinition("_target_qt_version");
  if (!qtVersion)
    {
    qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");
    if (!qtVersion)
      {
      qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
      }
    if (const char *targetQtVersion =
        target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION",
                                                        ""))
      {
      qtVersion = targetQtVersion;
      }
    }

  std::string targetName = target->GetName();
  if (strcmp(qtVersion, "5") == 0)
    {
    cmGeneratorTarget *qt5Rcc =
        lg->FindGeneratorTargetToUse("Qt5::rcc");
    if (!qt5Rcc)
      {
      cmSystemTools::Error("Qt5::rcc target not found ",
                          targetName.c_str());
      return std::string();
      }
    return qt5Rcc->ImportedGetLocation("");
    }
  else if (strcmp(qtVersion, "4") == 0)
    {
    cmGeneratorTarget *qt4Rcc =
        lg->FindGeneratorTargetToUse("Qt4::rcc");
    if (!qt4Rcc)
      {
      cmSystemTools::Error("Qt4::rcc target not found ",
                          targetName.c_str());
      return std::string();
      }
    return qt4Rcc->ImportedGetLocation("");
    }

  cmSystemTools::Error("The CMAKE_AUTORCC feature supports only Qt 4 and "
                      "Qt 5 ", targetName.c_str());
  return std::string();
}

static void MergeRccOptions(std::vector<std::string> &opts,
                         const std::vector<std::string> &fileOpts,
                         bool isQt5)
{
  static const char* valueOptions[] = {
    "name",
    "root",
    "compress",
    "threshold"
  };
  std::vector<std::string> extraOpts;
  for(std::vector<std::string>::const_iterator it = fileOpts.begin();
      it != fileOpts.end(); ++it)
    {
    std::vector<std::string>::iterator existingIt
                                  = std::find(opts.begin(), opts.end(), *it);
    if (existingIt != opts.end())
      {
      const char *o = it->c_str();
      if (*o == '-')
        {
        ++o;
        }
      if (isQt5 && *o == '-')
        {
        ++o;
        }
      if (std::find_if(cmArrayBegin(valueOptions), cmArrayEnd(valueOptions),
                  cmStrCmp(*it)) != cmArrayEnd(valueOptions))
        {
        assert(existingIt + 1 != opts.end());
        *(existingIt + 1) = *(it + 1);
        ++it;
        }
      }
    else
      {
      extraOpts.push_back(*it);
      }
    }
  opts.insert(opts.end(), extraOpts.begin(), extraOpts.end());
}

std::string GetAutogenTargetName(
    cmGeneratorTarget const* target)
{
  std::string autogenTargetName = target->GetName();
  autogenTargetName += "_automoc";
  return autogenTargetName;
}

std::string GetAutogenTargetDir(
    cmGeneratorTarget const* target)
{
  cmMakefile* makefile = target->Target->GetMakefile();
  std::string targetDir = makefile->GetCurrentBinaryDirectory();
  targetDir += makefile->GetCMakeInstance()->GetCMakeFilesDirectory();
  targetDir += "/";
  targetDir += GetAutogenTargetName(target);
  targetDir += ".dir/";
  return targetDir;
}

static void copyTargetProperty(cmTarget* destinationTarget,
                               cmTarget* sourceTarget,
                               const std::string& propertyName)
{
  const char* propertyValue = sourceTarget->GetProperty(propertyName);
  if (propertyValue)
    {
    destinationTarget->SetProperty(propertyName, propertyValue);
    }
}

static std::string cmQtAutoGeneratorsStripCR(std::string const& line)
{
  // Strip CR characters rcc may have printed (possibly more than one!).
  std::string::size_type cr = line.find('\r');
  if (cr != line.npos)
    {
    return line.substr(0, cr);
    }
  return line;
}

static std::string ReadAll(const std::string& filename)
{
  cmsys::ifstream file(filename.c_str());
  std::stringstream stream;
  stream << file.rdbuf();
  file.close();
  return stream.str();
}

static std::string ListQt5RccInputs(cmSourceFile* sf,
                                            cmGeneratorTarget const* target,
                                            std::vector<std::string>& depends)
{
  std::string rccCommand
      = GetRccExecutable(target);

  bool hasDashDashList = false;
  {
  std::vector<std::string> command;
  command.push_back(rccCommand);
  command.push_back("--help");
  std::string rccStdOut;
  std::string rccStdErr;
  int retVal = 0;
  bool result = cmSystemTools::RunSingleCommand(
    command, &rccStdOut, &rccStdErr,
    &retVal, 0, cmSystemTools::OUTPUT_NONE);
  if (result && retVal == 0 &&
      rccStdOut.find("--list") != std::string::npos)
    {
    hasDashDashList = true;
    }
  }

  std::vector<std::string> qrcEntries;

  std::vector<std::string> command;
  command.push_back(rccCommand);
  command.push_back(hasDashDashList? "--list" : "-list");

  std::string absFile = cmsys::SystemTools::GetRealPath(
                                              sf->GetFullPath());

  command.push_back(absFile);

  std::string rccStdOut;
  std::string rccStdErr;
  int retVal = 0;
  bool result = cmSystemTools::RunSingleCommand(
    command, &rccStdOut, &rccStdErr,
    &retVal, 0, cmSystemTools::OUTPUT_NONE);
  if (!result || retVal)
    {
    std::cerr << "AUTOGEN: error: Rcc list process for " << sf->GetFullPath()
              << " failed:\n" << rccStdOut << "\n" << rccStdErr << std::endl;
    return std::string();
    }

  {
  std::istringstream ostr(rccStdOut);
  std::string oline;
  while(std::getline(ostr, oline))
    {
    oline = cmQtAutoGeneratorsStripCR(oline);
    if(!oline.empty())
      {
      qrcEntries.push_back(oline);
      }
    }
  }

  {
  std::istringstream estr(rccStdErr);
  std::string eline;
  while(std::getline(estr, eline))
    {
    eline = cmQtAutoGeneratorsStripCR(eline);
    if (cmHasLiteralPrefix(eline, "RCC: Error in"))
      {
      static std::string searchString = "Cannot find file '";

      std::string::size_type pos = eline.find(searchString);
      if (pos == std::string::npos)
        {
        std::cerr << "AUTOGEN: error: Rcc lists unparsable output "
                  << eline << std::endl;
        return std::string();
        }
      pos += searchString.length();
      std::string::size_type sz = eline.size() - pos - 1;
      qrcEntries.push_back(eline.substr(pos, sz));
      }
    }
  }

  depends.insert(depends.end(), qrcEntries.begin(), qrcEntries.end());
  return cmJoin(qrcEntries, "@list_sep@");
}

static std::string ListQt4RccInputs(cmSourceFile* sf,
                                            std::vector<std::string>& depends)
{
  const std::string qrcContents = ReadAll(sf->GetFullPath());

  cmsys::RegularExpression fileMatchRegex("(<file[^<]+)");

  std::string entriesList;
  const char* sep = "";

  size_t offset = 0;
  while (fileMatchRegex.find(qrcContents.c_str() + offset))
    {
    std::string qrcEntry = fileMatchRegex.match(1);

    offset += qrcEntry.size();

    cmsys::RegularExpression fileReplaceRegex("(^<file[^>]*>)");
    fileReplaceRegex.find(qrcEntry);
    std::string tag = fileReplaceRegex.match(1);

    qrcEntry = qrcEntry.substr(tag.size());

    if (!cmSystemTools::FileIsFullPath(qrcEntry.c_str()))
      {
      qrcEntry = sf->GetLocation().GetDirectory() + "/" + qrcEntry;
      }

    entriesList += sep;
    entriesList += qrcEntry;
    sep = "@list_sep@";
    depends.push_back(qrcEntry);
    }
  return entriesList;
}

static void SetupAutoRccTarget(cmGeneratorTarget const* target)
{
  std::string _rcc_files;
  const char* sepRccFiles = "";
  cmMakefile *makefile = target->Target->GetMakefile();

  std::vector<cmSourceFile*> srcFiles;
  target->GetConfigCommonSourceFiles(srcFiles);

  std::string qrcInputs;
  const char* qrcInputsSep = "";

  std::string rccFileFiles;
  std::string rccFileOptions;
  const char *optionSep = "";

  const char *qtVersion = makefile->GetDefinition("_target_qt_version");

  std::vector<std::string> rccOptions;
  if (const char* opts = target->GetProperty("AUTORCC_OPTIONS"))
    {
    cmSystemTools::ExpandListArgument(opts, rccOptions);
    }
  std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
  if (qtMajorVersion == "")
    {
    qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
    }

  for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
      fileIt != srcFiles.end();
      ++fileIt)
    {
    cmSourceFile* sf = *fileIt;
    std::string ext = sf->GetExtension();
    if (ext == "qrc")
      {
      std::string absFile = cmsys::SystemTools::GetRealPath(
                                                  sf->GetFullPath());
      bool skip = cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC"));

      if (!skip)
        {
        _rcc_files += sepRccFiles;
        _rcc_files += absFile;
        sepRccFiles = ";";

        if (const char *prop = sf->GetProperty("AUTORCC_OPTIONS"))
          {
          std::vector<std::string> optsVec;
          cmSystemTools::ExpandListArgument(prop, optsVec);
          MergeRccOptions(rccOptions, optsVec,
                                strcmp(qtVersion, "5") == 0);
          }

        if (!rccOptions.empty())
          {
          rccFileFiles += optionSep;
          rccFileFiles += absFile;
          rccFileOptions += optionSep;
          }
        const char *listSep = "";
        for(std::vector<std::string>::const_iterator it = rccOptions.begin();
            it != rccOptions.end();
            ++it)
          {
          rccFileOptions += listSep;
          rccFileOptions += *it;
          listSep = "@list_sep@";
          }
        optionSep = ";";

        std::vector<std::string> depends;

        std::string entriesList;
        if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")))
          {
          if (qtMajorVersion == "5")
            {
            entriesList = ListQt5RccInputs(sf, target, depends);
            }
          else
            {
            entriesList = ListQt4RccInputs(sf, depends);
            }
          if (entriesList.empty())
            {
            return;
            }
          }
        qrcInputs += qrcInputsSep;
        qrcInputs += entriesList;
        qrcInputsSep = ";";
        }
      }
    }
  makefile->AddDefinition("_qt_rcc_inputs_" + target->GetName(),
                      cmOutputConverter::EscapeForCMake(qrcInputs).c_str());

  makefile->AddDefinition("_rcc_files",
          cmOutputConverter::EscapeForCMake(_rcc_files).c_str());

  makefile->AddDefinition("_qt_rcc_options_files",
              cmOutputConverter::EscapeForCMake(rccFileFiles).c_str());
  makefile->AddDefinition("_qt_rcc_options_options",
            cmOutputConverter::EscapeForCMake(rccFileOptions).c_str());

  makefile->AddDefinition("_qt_rcc_executable",
              GetRccExecutable(target).c_str());
}

void cmQtAutoGeneratorInitializer::InitializeAutogenSources(
    cmGeneratorTarget* target)
{
  cmMakefile* makefile = target->Target->GetMakefile();

  if (target->GetPropertyAsBool("AUTOMOC"))
    {
    std::string automocTargetName = GetAutogenTargetName(target);
    std::string mocCppFile = makefile->GetCurrentBinaryDirectory();
    mocCppFile += "/";
    mocCppFile += automocTargetName;
    mocCppFile += ".cpp";
    makefile->GetOrCreateSource(mocCppFile, true);
    makefile->AppendProperty("ADDITIONAL_MAKE_CLEAN_FILES",
                            mocCppFile.c_str(), false);

    target->AddSource(mocCppFile);
    }
}

void cmQtAutoGeneratorInitializer::InitializeAutogenTarget(
                                                 cmLocalGenerator* lg,
                                                 cmGeneratorTarget* target)
{
  cmMakefile* makefile = target->Target->GetMakefile();

  std::string qtMajorVersion = makefile->GetSafeDefinition("QT_VERSION_MAJOR");
  if (qtMajorVersion == "")
    {
    qtMajorVersion = makefile->GetSafeDefinition("Qt5Core_VERSION_MAJOR");
    }

  // create a custom target for running generators at buildtime:
  std::string autogenTargetName = GetAutogenTargetName(target);

  std::string targetDir = GetAutogenTargetDir(target);

  cmCustomCommandLine currentLine;
  currentLine.push_back(cmSystemTools::GetCMakeCommand());
  currentLine.push_back("-E");
  currentLine.push_back("cmake_autogen");
  currentLine.push_back(targetDir);
  currentLine.push_back("$<CONFIGURATION>");

  cmCustomCommandLines commandLines;
  commandLines.push_back(currentLine);

  std::string workingDirectory = cmSystemTools::CollapseFullPath(
                                    "", makefile->GetCurrentBinaryDirectory());

  std::vector<std::string> depends;
  if (const char *autogenDepends =
                                target->GetProperty("AUTOGEN_TARGET_DEPENDS"))
    {
    cmSystemTools::ExpandListArgument(autogenDepends, depends);
    }
  std::vector<std::string> toolNames;
  if (target->GetPropertyAsBool("AUTOMOC"))
    {
    toolNames.push_back("moc");
    }
  if (target->GetPropertyAsBool("AUTOUIC"))
    {
    toolNames.push_back("uic");
    }
  if (target->GetPropertyAsBool("AUTORCC"))
    {
    toolNames.push_back("rcc");
    }

  std::string tools = toolNames[0];
  toolNames.erase(toolNames.begin());
  while (toolNames.size() > 1)
    {
    tools += ", " + toolNames[0];
    toolNames.erase(toolNames.begin());
    }
  if (toolNames.size() == 1)
    {
    tools += " and " + toolNames[0];
    }
  std::string autogenComment = "Automatic " + tools + " for target ";
  autogenComment += target->GetName();

#if defined(_WIN32) && !defined(__CYGWIN__)
  bool usePRE_BUILD = false;
  cmGlobalGenerator* gg = lg->GetGlobalGenerator();
  if(gg->GetName().find("Visual Studio") != std::string::npos)
    {
    cmGlobalVisualStudioGenerator* vsgg =
      static_cast<cmGlobalVisualStudioGenerator*>(gg);
    // Under VS >= 7 use a PRE_BUILD event instead of a separate target to
    // reduce the number of targets loaded into the IDE.
    // This also works around a VS 11 bug that may skip updating the target:
    //  https://connect.microsoft.com/VisualStudio/feedback/details/769495
    usePRE_BUILD = vsgg->GetVersion() >= cmGlobalVisualStudioGenerator::VS7;
    if(usePRE_BUILD)
      {
      for (std::vector<std::string>::iterator it = depends.begin();
            it != depends.end(); ++it)
        {
        if(!makefile->FindTargetToUse(it->c_str()))
          {
          usePRE_BUILD = false;
          break;
          }
        }
      }
    }
#endif

  std::vector<std::string> rcc_output;
  bool const isNinja =
    lg->GetGlobalGenerator()->GetName() == "Ninja";
  if(isNinja
#if defined(_WIN32) && !defined(__CYGWIN__)
        || usePRE_BUILD
#endif
        )
    {
    std::vector<cmSourceFile*> srcFiles;
    target->GetConfigCommonSourceFiles(srcFiles);
    for(std::vector<cmSourceFile*>::const_iterator fileIt = srcFiles.begin();
        fileIt != srcFiles.end();
        ++fileIt)
      {
      cmSourceFile* sf = *fileIt;
      std::string absFile = cmsys::SystemTools::GetRealPath(
                                                sf->GetFullPath());

      std::string ext = sf->GetExtension();

      if (target->GetPropertyAsBool("AUTORCC"))
        {
        if (ext == "qrc"
            && !cmSystemTools::IsOn(sf->GetPropertyForUser("SKIP_AUTORCC")))
          {
          std::string basename = cmsys::SystemTools::
                                  GetFilenameWithoutLastExtension(absFile);

          std::string rcc_output_dir = target->GetSupportDirectory();
          cmSystemTools::MakeDirectory(rcc_output_dir.c_str());
          std::string rcc_output_file = rcc_output_dir;
          rcc_output_file += "/qrc_" + basename + ".cpp";
          rcc_output.push_back(rcc_output_file);

          if (!cmSystemTools::IsOn(sf->GetPropertyForUser("GENERATED")))
            {
            if (qtMajorVersion == "5")
              {
              ListQt5RccInputs(sf, target, depends);
              }
            else
              {
              ListQt4RccInputs(sf, depends);
              }
#if defined(_WIN32) && !defined(__CYGWIN__)
            // Cannot use PRE_BUILD because the resource files themselves
            // may not be sources within the target so VS may not know the
            // target needs to re-build at all.
            usePRE_BUILD = false;
#endif
            }
          }
        }
      }
    }

#if defined(_WIN32) && !defined(__CYGWIN__)
  if(usePRE_BUILD)
    {
    // Add the pre-build command directly to bypass the OBJECT_LIBRARY
    // rejection in cmMakefile::AddCustomCommandToTarget because we know
    // PRE_BUILD will work for an OBJECT_LIBRARY in this specific case.
    std::vector<std::string> no_output;
    std::vector<std::string> no_byproducts;
    cmCustomCommand cc(makefile, no_output, no_byproducts, depends,
                       commandLines, autogenComment.c_str(),
                       workingDirectory.c_str());
    cc.SetEscapeOldStyle(false);
    cc.SetEscapeAllowMakeVars(true);
    target->Target->AddPreBuildCommand(cc);
    }
  else
#endif
    {
    cmTarget* autogenTarget = makefile->AddUtilityCommand(
                                autogenTargetName, true,
                                workingDirectory.c_str(),
                                /*byproducts=*/rcc_output, depends,
                                commandLines, false, autogenComment.c_str());

    cmGeneratorTarget* gt = new cmGeneratorTarget(autogenTarget, lg);
    lg->AddGeneratorTarget(gt);

    // Set target folder
    const char* autogenFolder = makefile->GetState()
                                ->GetGlobalProperty("AUTOMOC_TARGETS_FOLDER");
    if (!autogenFolder)
      {
      autogenFolder = makefile->GetState()
                                ->GetGlobalProperty("AUTOGEN_TARGETS_FOLDER");
      }
    if (autogenFolder && *autogenFolder)
      {
      autogenTarget->SetProperty("FOLDER", autogenFolder);
      }
    else
      {
      // inherit FOLDER property from target (#13688)
      copyTargetProperty(gt->Target, target->Target, "FOLDER");
      }

    target->Target->AddUtility(autogenTargetName);
    }
}

void cmQtAutoGeneratorInitializer::SetupAutoGenerateTarget(
    cmGeneratorTarget const* target)
{
  cmMakefile* makefile = target->Target->GetMakefile();

  // forget the variables added here afterwards again:
  cmMakefile::ScopePushPop varScope(makefile);
  static_cast<void>(varScope);

  // create a custom target for running generators at buildtime:
  std::string autogenTargetName = GetAutogenTargetName(target);

  makefile->AddDefinition("_moc_target_name",
          cmOutputConverter::EscapeForCMake(autogenTargetName).c_str());
  makefile->AddDefinition("_origin_target_name",
          cmOutputConverter::EscapeForCMake(target->GetName()).c_str());

  std::string targetDir = GetAutogenTargetDir(target);

  const char *qtVersion = makefile->GetDefinition("Qt5Core_VERSION_MAJOR");
  if (!qtVersion)
    {
    qtVersion = makefile->GetDefinition("QT_VERSION_MAJOR");
    }
  if (const char *targetQtVersion =
      target->GetLinkInterfaceDependentStringProperty("QT_MAJOR_VERSION", ""))
    {
    qtVersion = targetQtVersion;
    }
  if (qtVersion)
    {
    makefile->AddDefinition("_target_qt_version", qtVersion);
    }

  std::vector<std::string> skipUic;
  std::vector<std::string> skipMoc;
  std::vector<std::string> mocSources;
  std::vector<std::string> mocHeaders;
  std::map<std::string, std::string> configIncludes;
  std::map<std::string, std::string> configDefines;
  std::map<std::string, std::string> configUicOptions;

  if (target->GetPropertyAsBool("AUTOMOC")
      || target->GetPropertyAsBool("AUTOUIC")
      || target->GetPropertyAsBool("AUTORCC"))
    {
    SetupSourceFiles(target, skipMoc, mocSources, mocHeaders, skipUic);
    }
  makefile->AddDefinition("_cpp_files",
          cmOutputConverter::EscapeForCMake(cmJoin(mocSources, ";")).c_str());
  if (target->GetPropertyAsBool("AUTOMOC"))
    {
    SetupAutoMocTarget(target, autogenTargetName,
                             skipMoc, mocHeaders,
                             configIncludes, configDefines);
    }
  if (target->GetPropertyAsBool("AUTOUIC"))
    {
    SetupAutoUicTarget(target, skipUic, configUicOptions);
    }
  if (target->GetPropertyAsBool("AUTORCC"))
    {
    SetupAutoRccTarget(target);
    }

  const char* cmakeRoot = makefile->GetSafeDefinition("CMAKE_ROOT");
  std::string inputFile = cmakeRoot;
  inputFile += "/Modules/AutogenInfo.cmake.in";
  std::string outputFile = targetDir;
  outputFile += "/AutogenInfo.cmake";
  makefile->AddDefinition("_qt_rcc_inputs",
              makefile->GetDefinition("_qt_rcc_inputs_" + target->GetName()));
  makefile->ConfigureFile(inputFile.c_str(), outputFile.c_str(),
                          false, true, false);

  // Ensure we have write permission in case .in was read-only.
  mode_t perm = 0;
#if defined(_WIN32) && !defined(__CYGWIN__)
  mode_t mode_write = S_IWRITE;
#else
  mode_t mode_write = S_IWUSR;
#endif
  cmSystemTools::GetPermissions(outputFile, perm);
  if (!(perm & mode_write))
    {
    cmSystemTools::SetPermissions(outputFile, perm | mode_write);
    }
  if (!configDefines.empty()
      || !configIncludes.empty()
      || !configUicOptions.empty())
    {
    cmsys::ofstream infoFile(outputFile.c_str(), std::ios::app);
    if ( !infoFile )
      {
      std::string error = "Internal CMake error when trying to open file: ";
      error += outputFile.c_str();
      error += " for writing.";
      cmSystemTools::Error(error.c_str());
      return;
      }
    if (!configDefines.empty())
      {
      for (std::map<std::string, std::string>::iterator
            it = configDefines.begin(), end = configDefines.end();
            it != end; ++it)
        {
        infoFile << "set(AM_MOC_COMPILE_DEFINITIONS_" << it->first <<
          " " << it->second << ")\n";
        }
      }
    if (!configIncludes.empty())
      {
      for (std::map<std::string, std::string>::iterator
            it = configIncludes.begin(), end = configIncludes.end();
            it != end; ++it)
        {
        infoFile << "set(AM_MOC_INCLUDES_" << it->first <<
          " " << it->second << ")\n";
        }
      }
    if (!configUicOptions.empty())
      {
      for (std::map<std::string, std::string>::iterator
            it = configUicOptions.begin(), end = configUicOptions.end();
            it != end; ++it)
        {
        infoFile << "set(AM_UIC_TARGET_OPTIONS_" << it->first <<
          " " << it->second << ")\n";
        }
      }
    }
}
