#include "cmVisualStudioGeneratorOptions.h"

#include "cmAlgorithms.h"
#include "cmLocalVisualStudioGenerator.h"
#include "cmOutputConverter.h"
#include "cmSystemTools.h"
#include "cmVisualStudio10TargetGenerator.h"

static std::string cmVisualStudio10GeneratorOptionsEscapeForXML(
  std::string ret)
{
  cmSystemTools::ReplaceString(ret, ";", "%3B");
  cmSystemTools::ReplaceString(ret, "&", "&amp;");
  cmSystemTools::ReplaceString(ret, "<", "&lt;");
  cmSystemTools::ReplaceString(ret, ">", "&gt;");
  return ret;
}

static std::string cmVisualStudioGeneratorOptionsEscapeForXML(std::string ret)
{
  cmSystemTools::ReplaceString(ret, "&", "&amp;");
  cmSystemTools::ReplaceString(ret, "\"", "&quot;");
  cmSystemTools::ReplaceString(ret, "<", "&lt;");
  cmSystemTools::ReplaceString(ret, ">", "&gt;");
  cmSystemTools::ReplaceString(ret, "\n", "&#x0D;&#x0A;");
  return ret;
}

cmVisualStudioGeneratorOptions::cmVisualStudioGeneratorOptions(
  cmLocalVisualStudioGenerator* lg, Tool tool,
  cmVisualStudio10TargetGenerator* g)
  : cmIDEOptions()
  , LocalGenerator(lg)
  , Version(lg->GetVersion())
  , CurrentTool(tool)
  , TargetGenerator(g)
{
  // Preprocessor definitions are not allowed for linker tools.
  this->AllowDefine = (tool != Linker);

  // Slash options are allowed for VS.
  this->AllowSlash = true;

  this->FortranRuntimeDebug = false;
  this->FortranRuntimeDLL = false;
  this->FortranRuntimeMT = false;
}

cmVisualStudioGeneratorOptions::cmVisualStudioGeneratorOptions(
  cmLocalVisualStudioGenerator* lg, Tool tool, cmVS7FlagTable const* table,
  cmVS7FlagTable const* extraTable, cmVisualStudio10TargetGenerator* g)
  : cmIDEOptions()
  , LocalGenerator(lg)
  , Version(lg->GetVersion())
  , CurrentTool(tool)
  , TargetGenerator(g)
{
  // Store the given flag tables.
  this->AddTable(table);
  this->AddTable(extraTable);

  // Preprocessor definitions are not allowed for linker tools.
  this->AllowDefine = (tool != Linker);

  // Slash options are allowed for VS.
  this->AllowSlash = true;

  this->FortranRuntimeDebug = false;
  this->FortranRuntimeDLL = false;
  this->FortranRuntimeMT = false;
}

void cmVisualStudioGeneratorOptions::AddTable(cmVS7FlagTable const* table)
{
  if (table) {
    for (int i = 0; i < FlagTableCount; ++i) {
      if (!this->FlagTable[i]) {
        this->FlagTable[i] = table;
        break;
      }
    }
  }
}

void cmVisualStudioGeneratorOptions::FixExceptionHandlingDefault()
{
  // Exception handling is on by default because the platform file has
  // "/EHsc" in the flags.  Normally, that will override this
  // initialization to off, but the user has the option of removing
  // the flag to disable exception handling.  When the user does
  // remove the flag we need to override the IDE default of on.
  switch (this->Version) {
    case cmGlobalVisualStudioGenerator::VS7:
    case cmGlobalVisualStudioGenerator::VS71:
      this->FlagMap["ExceptionHandling"] = "FALSE";
      break;
    case cmGlobalVisualStudioGenerator::VS10:
    case cmGlobalVisualStudioGenerator::VS11:
    case cmGlobalVisualStudioGenerator::VS12:
    case cmGlobalVisualStudioGenerator::VS14:
    case cmGlobalVisualStudioGenerator::VS15:
      // by default VS puts <ExceptionHandling></ExceptionHandling> empty
      // for a project, to make our projects look the same put a new line
      // and space over for the closing </ExceptionHandling> as the default
      // value
      this->FlagMap["ExceptionHandling"] = "\n      ";
      break;
    default:
      this->FlagMap["ExceptionHandling"] = "0";
      break;
  }
}

void cmVisualStudioGeneratorOptions::SetVerboseMakefile(bool verbose)
{
  // If verbose makefiles have been requested and the /nologo option
  // was not given explicitly in the flags we want to add an attribute
  // to the generated project to disable logo suppression.  Otherwise
  // the GUI default is to enable suppression.
  //
  // On Visual Studio 10 (and later!), the value of this attribute should be
  // an empty string, instead of "FALSE", in order to avoid a warning:
  //   "cl ... warning D9035: option 'nologo-' has been deprecated"
  //
  if (verbose &&
      this->FlagMap.find("SuppressStartupBanner") == this->FlagMap.end()) {
    this->FlagMap["SuppressStartupBanner"] =
      this->Version < cmGlobalVisualStudioGenerator::VS10 ? "FALSE" : "";
  }
}

bool cmVisualStudioGeneratorOptions::IsDebug() const
{
  if (this->CurrentTool != CSharpCompiler) {
    return this->FlagMap.find("DebugInformationFormat") != this->FlagMap.end();
  }
  std::map<std::string, FlagValue>::const_iterator i =
    this->FlagMap.find("DebugType");
  if (i != this->FlagMap.end()) {
    if (i->second.size() == 1) {
      return i->second[0] != "none";
    }
  }
  return false;
}

bool cmVisualStudioGeneratorOptions::IsWinRt() const
{
  return this->FlagMap.find("CompileAsWinRT") != this->FlagMap.end();
}

bool cmVisualStudioGeneratorOptions::IsManaged() const
{
  return this->FlagMap.find("CompileAsManaged") != this->FlagMap.end();
}

bool cmVisualStudioGeneratorOptions::UsingUnicode() const
{
  // Look for the a _UNICODE definition.
  for (std::vector<std::string>::const_iterator di = this->Defines.begin();
       di != this->Defines.end(); ++di) {
    if (*di == "_UNICODE") {
      return true;
    }
  }
  return false;
}
bool cmVisualStudioGeneratorOptions::UsingSBCS() const
{
  // Look for the a _SBCS definition.
  for (std::vector<std::string>::const_iterator di = this->Defines.begin();
       di != this->Defines.end(); ++di) {
    if (*di == "_SBCS") {
      return true;
    }
  }
  return false;
}

void cmVisualStudioGeneratorOptions::Parse(const char* flags)
{
  // Parse the input string as a windows command line since the string
  // is intended for writing directly into the build files.
  std::vector<std::string> args;
  cmSystemTools::ParseWindowsCommandLine(flags, args);

  // Process flags that need to be represented specially in the IDE
  // project file.
  for (std::vector<std::string>::iterator ai = args.begin(); ai != args.end();
       ++ai) {
    this->HandleFlag(ai->c_str());
  }
}

void cmVisualStudioGeneratorOptions::ParseFinish()
{
  if (this->CurrentTool == FortranCompiler) {
    // "RuntimeLibrary" attribute values:
    //  "rtMultiThreaded", "0", /threads /libs:static
    //  "rtMultiThreadedDLL", "2", /threads /libs:dll
    //  "rtMultiThreadedDebug", "1", /threads /dbglibs /libs:static
    //  "rtMultiThreadedDebugDLL", "3", /threads /dbglibs /libs:dll
    // These seem unimplemented by the IDE:
    //  "rtSingleThreaded", "4", /libs:static
    //  "rtSingleThreadedDLL", "10", /libs:dll
    //  "rtSingleThreadedDebug", "5", /dbglibs /libs:static
    //  "rtSingleThreadedDebugDLL", "11", /dbglibs /libs:dll
    std::string rl = "rtMultiThreaded";
    rl += this->FortranRuntimeDebug ? "Debug" : "";
    rl += this->FortranRuntimeDLL ? "DLL" : "";
    this->FlagMap["RuntimeLibrary"] = rl;
  }
}

void cmVisualStudioGeneratorOptions::StoreUnknownFlag(const char* flag)
{
  // Look for Intel Fortran flags that do not map well in the flag table.
  if (this->CurrentTool == FortranCompiler) {
    if (strcmp(flag, "/dbglibs") == 0) {
      this->FortranRuntimeDebug = true;
      return;
    }
    if (strcmp(flag, "/threads") == 0) {
      this->FortranRuntimeMT = true;
      return;
    }
    if (strcmp(flag, "/libs:dll") == 0) {
      this->FortranRuntimeDLL = true;
      return;
    }
    if (strcmp(flag, "/libs:static") == 0) {
      this->FortranRuntimeDLL = false;
      return;
    }
  }

  // This option is not known.  Store it in the output flags.
  this->FlagString += " ";
  this->FlagString += cmOutputConverter::EscapeWindowsShellArgument(
    flag, cmOutputConverter::Shell_Flag_AllowMakeVariables |
      cmOutputConverter::Shell_Flag_VSIDE);
}

void cmVisualStudioGeneratorOptions::SetConfiguration(const char* config)
{
  this->Configuration = config;
}

void cmVisualStudioGeneratorOptions::OutputPreprocessorDefinitions(
  std::ostream& fout, const char* prefix, const char* suffix,
  const std::string& lang)
{
  if (this->Defines.empty()) {
    return;
  }
  if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
    // if there are configuration specific flags, then
    // use the configuration specific tag for PreprocessorDefinitions
    if (!this->Configuration.empty()) {
      fout << prefix;
      this->TargetGenerator->WritePlatformConfigTag(
        "PreprocessorDefinitions", this->Configuration.c_str(), 0, 0, 0,
        &fout);
    } else {
      fout << prefix << "<PreprocessorDefinitions>";
    }
  } else {
    fout << prefix << "PreprocessorDefinitions=\"";
  }
  const char* sep = "";
  std::vector<std::string>::const_iterator de =
    cmRemoveDuplicates(this->Defines);
  for (std::vector<std::string>::const_iterator di = this->Defines.begin();
       di != de; ++di) {
    // Escape the definition for the compiler.
    std::string define;
    if (this->Version < cmGlobalVisualStudioGenerator::VS10) {
      define = this->LocalGenerator->EscapeForShell(di->c_str(), true);
    } else {
      define = *di;
    }
    // Escape this flag for the IDE.
    if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
      define = cmVisualStudio10GeneratorOptionsEscapeForXML(define);

      if (lang == "RC") {
        cmSystemTools::ReplaceString(define, "\"", "\\\"");
      }
    } else {
      define = cmVisualStudioGeneratorOptionsEscapeForXML(define);
    }
    // Store the flag in the project file.
    fout << sep << define;
    sep = ";";
  }
  if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
    fout << ";%(PreprocessorDefinitions)</PreprocessorDefinitions>" << suffix;
  } else {
    fout << "\"" << suffix;
  }
}

void cmVisualStudioGeneratorOptions::OutputFlagMap(std::ostream& fout,
                                                   const char* indent)
{
  if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
    for (std::map<std::string, FlagValue>::iterator m = this->FlagMap.begin();
         m != this->FlagMap.end(); ++m) {
      fout << indent;
      if (!this->Configuration.empty()) {
        this->TargetGenerator->WritePlatformConfigTag(
          m->first.c_str(), this->Configuration.c_str(), 0, 0, 0, &fout);
      } else {
        fout << "<" << m->first << ">";
      }
      const char* sep = "";
      for (std::vector<std::string>::iterator i = m->second.begin();
           i != m->second.end(); ++i) {
        fout << sep << cmVisualStudio10GeneratorOptionsEscapeForXML(*i);
        sep = ";";
      }
      fout << "</" << m->first << ">\n";
    }
  } else {
    for (std::map<std::string, FlagValue>::iterator m = this->FlagMap.begin();
         m != this->FlagMap.end(); ++m) {
      fout << indent << m->first << "=\"";
      const char* sep = "";
      for (std::vector<std::string>::iterator i = m->second.begin();
           i != m->second.end(); ++i) {
        fout << sep << cmVisualStudioGeneratorOptionsEscapeForXML(*i);
        sep = ";";
      }
      fout << "\"\n";
    }
  }
}

void cmVisualStudioGeneratorOptions::OutputAdditionalOptions(
  std::ostream& fout, const char* prefix, const char* suffix)
{
  if (!this->FlagString.empty()) {
    if (this->Version >= cmGlobalVisualStudioGenerator::VS10) {
      fout << prefix;
      if (!this->Configuration.empty()) {
        this->TargetGenerator->WritePlatformConfigTag(
          "AdditionalOptions", this->Configuration.c_str(), 0, 0, 0, &fout);
      } else {
        fout << "<AdditionalOptions>";
      }
      fout << "%(AdditionalOptions) "
           << cmVisualStudio10GeneratorOptionsEscapeForXML(this->FlagString)
           << "</AdditionalOptions>\n";
    } else {
      fout << prefix << "AdditionalOptions=\"";
      fout << cmVisualStudioGeneratorOptionsEscapeForXML(this->FlagString);
      fout << "\"" << suffix;
    }
  }
}
