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

#include <utility>

#include <cm/memory>
#include <cmext/string_view>

#include "windows.h"

#include "cmCustomCommand.h"
#include "cmCustomCommandGenerator.h"
#include "cmCustomCommandLines.h"
#include "cmGeneratorTarget.h"
#include "cmGlobalGenerator.h"
#include "cmMakefile.h"
#include "cmOutputConverter.h"
#include "cmSourceFile.h"
#include "cmStateTypes.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"

cmLocalVisualStudioGenerator::cmLocalVisualStudioGenerator(
  cmGlobalGenerator* gg, cmMakefile* mf)
  : cmLocalGenerator(gg, mf)
{
}

cmLocalVisualStudioGenerator::~cmLocalVisualStudioGenerator() = default;

cmGlobalVisualStudioGenerator::VSVersion
cmLocalVisualStudioGenerator::GetVersion() const
{
  cmGlobalVisualStudioGenerator* gg =
    static_cast<cmGlobalVisualStudioGenerator*>(this->GlobalGenerator);
  return gg->GetVersion();
}

void cmLocalVisualStudioGenerator::ComputeObjectFilenames(
  std::map<cmSourceFile const*, cmObjectLocations>& mapping,
  std::string const& config, cmGeneratorTarget const* gt)
{
  char const* custom_ext = gt->GetCustomObjectExtension();
  std::string dir_max = this->ComputeLongestObjectDirectory(gt);

  // Count the number of object files with each name.  Note that
  // windows file names are not case sensitive.
  std::map<std::string, int> counts;

  for (auto const& si : mapping) {
    cmSourceFile const* sf = si.first;
    std::string baseObjectName;
    if (gt->GetUseShortObjectNames()) {
      baseObjectName = this->GetShortObjectFileName(*sf);
    } else {
      auto customObjectName = this->GetCustomObjectFileName(*sf);
      if (customObjectName.empty()) {
        baseObjectName =
          cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
      } else {
        baseObjectName = std::move(customObjectName);
      }
    }
    std::string objectNameLower = cmSystemTools::LowerCase(baseObjectName);
    if (custom_ext) {
      objectNameLower += custom_ext;
    } else {
      objectNameLower +=
        this->GlobalGenerator->GetLanguageOutputExtension(*sf);
    }
    counts[objectNameLower] += 1;
  }

  // For all source files producing duplicate names we need unique
  // object name computation.

  for (auto& si : mapping) {
    cmSourceFile const* sf = si.first;
    std::string shortObjectName = this->GetShortObjectFileName(*sf);
    std::string longObjectName;
    auto customObjectName = this->GetCustomObjectFileName(*sf);
    if (customObjectName.empty()) {
      longObjectName =
        cmSystemTools::GetFilenameWithoutLastExtension(sf->GetFullPath());
    } else {
      longObjectName = std::move(customObjectName);
      const_cast<cmGeneratorTarget*>(gt)->AddExplicitObjectName(sf);
    }
    if (custom_ext) {
      shortObjectName += custom_ext;
      longObjectName += custom_ext;
    } else {
      shortObjectName +=
        this->GlobalGenerator->GetLanguageOutputExtension(*sf);
      longObjectName += this->GlobalGenerator->GetLanguageOutputExtension(*sf);
    }
    if (counts[cmSystemTools::LowerCase(longObjectName)] > 1) {
      const_cast<cmGeneratorTarget*>(gt)->AddExplicitObjectName(sf);
      bool keptSourceExtension;
      bool forceShortObjectName = false;
      longObjectName = this->GetObjectFileNameWithoutTarget(
        *sf, dir_max, &keptSourceExtension, custom_ext, &forceShortObjectName);
    }
    si.second.ShortLoc.emplace(shortObjectName);
    si.second.LongLoc.Update(longObjectName);
    this->FillCustomInstallObjectLocations(*sf, config, custom_ext,
                                           si.second.InstallLongLoc);
  }
}

std::string cmLocalVisualStudioGenerator::GetObjectOutputRoot(
  cmStateEnums::IntermediateDirKind kind) const
{
  if (this->UseShortObjectNames(kind)) {
    return cmStrCat(this->GetCurrentBinaryDirectory(), '/',
                    this->GetGlobalGenerator()->GetShortBinaryOutputDir());
  }
  return this->GetCurrentBinaryDirectory();
}

bool cmLocalVisualStudioGenerator::AlwaysUsesCMFPaths() const
{
  return false;
}

std::unique_ptr<cmCustomCommand>
cmLocalVisualStudioGenerator::MaybeCreateImplibDir(cmGeneratorTarget* target,
                                                   std::string const& config,
                                                   bool isFortran)
{
  std::unique_ptr<cmCustomCommand> pcc;

  // If an executable exports symbols then VS wants to create an
  // import library but forgets to create the output directory.
  // The Intel Fortran plugin always forgets to the directory.
  if (target->GetType() != cm::TargetType::EXECUTABLE &&
      !(isFortran && target->GetType() == cm::TargetType::SHARED_LIBRARY)) {
    return pcc;
  }
  std::string outDir =
    target->GetDirectory(config, cmStateEnums::RuntimeBinaryArtifact);
  std::string impDir =
    target->GetDirectory(config, cmStateEnums::ImportLibraryArtifact);
  if (impDir == outDir) {
    return pcc;
  }

  // Add a pre-build event to create the directory.
  cmCustomCommandLines commands = cmMakeSingleCommandLine(
    { cmSystemTools::GetCMakeCommand(), "-E", "make_directory", impDir });
  pcc = cm::make_unique<cmCustomCommand>();
  pcc->SetCommandLines(commands);
  pcc->SetStdPipesUTF8(true);
  pcc->SetEscapeOldStyle(false);
  pcc->SetEscapeAllowMakeVars(true);
  return pcc;
}

char const* cmLocalVisualStudioGenerator::ReportErrorLabel() const
{
  return ":VCReportError";
}

char const* cmLocalVisualStudioGenerator::GetReportErrorLabel() const
{
  return this->ReportErrorLabel();
}

std::string cmLocalVisualStudioGenerator::ConstructScript(
  cmCustomCommandGenerator const& ccg, std::string const& newline_text)
{
  bool useLocal = this->CustomCommandUseLocal();
  std::string workingDirectory = ccg.GetWorkingDirectory();

  // Avoid leading or trailing newlines.
  std::string newline;

  // Line to check for error between commands.
  std::string check_error;
  if (useLocal) {
    check_error = cmStrCat(newline_text, "if %errorlevel% neq 0 goto :cmEnd");
  } else {
    check_error = cmStrCat(newline_text, "if errorlevel 1 goto ",
                           this->GetReportErrorLabel());
  }

  // Store the script in a string.
  std::string script;

  // Open a local context.
  if (useLocal) {
    script = cmStrCat(newline, "setlocal");
    newline = newline_text;
  }

  if (!workingDirectory.empty()) {
    // Change the working directory.
    script = cmStrCat(script, newline, "cd ",
                      this->ConvertToOutputFormat(workingDirectory, SHELL),
                      check_error);
    newline = newline_text;

    // Change the working drive.
    if (workingDirectory.size() > 1 && workingDirectory[1] == ':') {
      script = cmStrCat(script, newline, workingDirectory[0],
                        workingDirectory[1], check_error);
      newline = newline_text;
    }
  }

  // for visual studio IDE add extra stuff to the PATH
  // if CMAKE_MSVCIDE_RUN_PATH is set.
  if (this->GetGlobalGenerator()->IsVisualStudio()) {
    cmValue extraPath =
      this->Makefile->GetDefinition("CMAKE_MSVCIDE_RUN_PATH");
    if (extraPath) {
      script = cmStrCat(script, newline, "set PATH=", *extraPath, ";%PATH%");
      newline = newline_text;
    }
  }

  // Write each command on a single line.
  for (unsigned int c = 0; c < ccg.GetNumberOfCommands(); ++c) {
    // Add this command line.
    std::string cmd = ccg.GetCommand(c);

    if (cmd.empty()) {
      continue;
    }

    // Start a new line.
    script += newline;
    newline = newline_text;

    // Use "call " before any invocations of .bat or .cmd files
    // invoked as custom commands.
    //
    std::string suffix;
    if (cmd.size() > 4) {
      suffix = cmSystemTools::LowerCase(cmd.substr(cmd.size() - 4));
      if (suffix == ".bat"_s || suffix == ".cmd"_s) {
        script += "call ";
      }
    }

    if (workingDirectory.empty()) {
      script += this->ConvertToOutputFormat(
        this->MaybeRelativeToCurBinDir(cmd), cmOutputConverter::SHELL);
    } else {
      script += this->ConvertToOutputFormat(cmd.c_str(), SHELL);
    }
    ccg.AppendArguments(c, script);

    // After each custom command, check for an error result.
    // If there was an error, jump to the VCReportError label,
    // skipping the run of any subsequent commands in this
    // sequence.
    script += check_error;
  }

  // Close the local context.
  if (useLocal) {
    // clang-format off
    script = cmStrCat(
        script
      , newline
      , ":cmEnd"
      , newline
      , "endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone"
      , newline
      , ":cmErrorLevel"
      , newline
      , "exit /b %1"
      , newline
      , ":cmDone"
      , newline
      , "if %errorlevel% neq 0 goto ", this->GetReportErrorLabel()
      );
    // clang-format on
  }

  return script;
}

std::string cmLocalVisualStudioGenerator::FinishConstructScript(
  VsProjectType projectType, std::string const& newline)
{
  bool useLocal = this->CustomCommandUseLocal();

  // Store the script in a string.
  std::string script;

  if (useLocal && projectType != VsProjectType::vcxproj) {
    // This label is not provided by MSBuild for C# projects.
    script += newline;
    script += this->GetReportErrorLabel();
  }

  return script;
}
