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

#include <chrono>
#include <sstream>
#include <string>
#include <vector>

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

#include "cmArgumentParser.h"
#include "cmCLocaleEnvironmentScope.h"
#include "cmCTest.h"
#include "cmCTestBZR.h"
#include "cmCTestCVS.h"
#include "cmCTestGIT.h"
#include "cmCTestHG.h"
#include "cmCTestP4.h"
#include "cmCTestSVN.h"
#include "cmCTestVC.h"
#include "cmExecutionStatus.h"
#include "cmGeneratedFileStream.h"
#include "cmMakefile.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"
#include "cmXMLWriter.h"

namespace {

enum
{
  e_UNKNOWN = 0,
  e_CVS,
  e_SVN,
  e_BZR,
  e_GIT,
  e_HG,
  e_P4,
  e_LAST
};

char const* TypeToString(int type)
{
  // clang-format off
  switch (type) {
    case e_CVS: return "CVS";
    case e_SVN: return "SVN";
    case e_BZR: return "BZR";
    case e_GIT: return "GIT";
    case e_HG:  return "HG";
    case e_P4:  return "P4";
    default:    return "Unknown";
  }
  // clang-format on
}

char const* TypeToCommandKey(int type)
{
  // clang-format off
  switch (type) {
    case e_CVS: return "CTEST_CVS_COMMAND";
    case e_SVN: return "CTEST_SVN_COMMAND";
    case e_BZR: return "CTEST_BZR_COMMAND";
    case e_GIT: return "CTEST_GIT_COMMAND";
    case e_HG:  return "CTEST_HG_COMMAND";
    case e_P4:  return "CTEST_P4_COMMAND";
    default:    return nullptr;
  }
  // clang-format on
}

int DetermineType(std::string const& cmd)
{
  std::string stype = cmSystemTools::LowerCase(cmd);
  if (stype.find("cvs") != std::string::npos) {
    return e_CVS;
  }
  if (stype.find("svn") != std::string::npos) {
    return e_SVN;
  }
  if (stype.find("bzr") != std::string::npos) {
    return e_BZR;
  }
  if (stype.find("git") != std::string::npos) {
    return e_GIT;
  }
  if (stype.find("hg") != std::string::npos) {
    return e_HG;
  }
  if (stype.find("p4") != std::string::npos) {
    return e_P4;
  }
  return e_UNKNOWN;
}

int DetectVCS(std::string const& dir)
{
  if (cmSystemTools::FileExists(cmStrCat(dir, "/CVS"))) {
    return e_CVS;
  }
  if (cmSystemTools::FileExists(cmStrCat(dir, "/.svn"))) {
    return e_SVN;
  }
  if (cmSystemTools::FileExists(cmStrCat(dir, "/.bzr"))) {
    return e_BZR;
  }
  if (cmSystemTools::FileExists(cmStrCat(dir, "/.git"))) {
    return e_GIT;
  }
  if (cmSystemTools::FileExists(cmStrCat(dir, "/.hg"))) {
    return e_HG;
  }
  if (cmSystemTools::FileExists(cmStrCat(dir, "/.p4"))) {
    return e_P4;
  }
  if (cmSystemTools::FileExists(cmStrCat(dir, "/.p4config"))) {
    return e_P4;
  }
  return e_UNKNOWN;
}

std::unique_ptr<cmCTestVC> MakeVC(int type, cmCTest* ctest, cmMakefile* mf,
                                  std::ostream& os)
{
  // clang-format off
  switch (type) {
    case e_CVS: return cm::make_unique<cmCTestCVS>(ctest, mf, os);
    case e_SVN: return cm::make_unique<cmCTestSVN>(ctest, mf, os);
    case e_BZR: return cm::make_unique<cmCTestBZR>(ctest, mf, os);
    case e_GIT: return cm::make_unique<cmCTestGIT>(ctest, mf, os);
    case e_HG:  return cm::make_unique<cmCTestHG> (ctest, mf, os);
    case e_P4:  return cm::make_unique<cmCTestP4> (ctest, mf, os);
    default:    return cm::make_unique<cmCTestVC> (ctest, mf, os);
  }
  // clang-format on
}

} // namespace

bool cmCTestUpdateCommand::ExecuteUpdate(UpdateArguments& args,
                                         cmExecutionStatus& status) const
{
  cmMakefile& mf = status.GetMakefile();

  std::string const& source_dir = !args.Source.empty()
    ? args.Source
    : mf.GetSafeDefinition("CTEST_SOURCE_DIRECTORY");
  if (source_dir.empty()) {
    status.SetError("called with no source directory specified. "
                    "Use SOURCE argument or set CTEST_SOURCE_DIRECTORY.");
    return false;
  }

  std::string const currentTag = this->CTest->GetCurrentTag();
  if (currentTag.empty()) {
    status.SetError("called with no current tag.");
    return false;
  }

  // Detect the VCS managing the source tree.
  int updateType = DetectVCS(source_dir);

  // Get update command
  std::string updateCommand = mf.GetSafeDefinition("CTEST_UPDATE_COMMAND");

  if (updateType == e_UNKNOWN && !updateCommand.empty()) {
    updateType = DetermineType(updateCommand);
  }
  if (updateType == e_UNKNOWN) {
    updateType = DetermineType(mf.GetSafeDefinition("CTEST_UPDATE_TYPE"));
  }

  // If no update command was specified, lookup one for this VCS tool.
  if (updateCommand.empty()) {
    const char* key = TypeToCommandKey(updateType);
    if (key) {
      updateCommand = mf.GetSafeDefinition(key);
    }

    if (updateCommand.empty()) {
      std::ostringstream e;
      e << "called with no update command specified. "
           "Please set CTEST_UPDATE_COMMAND";
      if (key) {
        e << " or " << key;
      }
      e << '.';
      status.SetError(e.str());
      return false;
    }
  }

  cmGeneratedFileStream ofs;
  if (!this->CTest->GetShowOnly()) {
    std::string logFile = cmStrCat("LastUpdate_", currentTag, ".log");
    if (!this->CTest->OpenOutputFile("Temporary", logFile, ofs)) {
      status.SetError(cmStrCat("cannot create log file: ", logFile));
      return false;
    }
  }

  cmGeneratedFileStream os;
  if (!this->CTest->OpenOutputFile(currentTag, "Update.xml", os, true)) {
    status.SetError("cannot create resulting XML file: Update.xml");
    return false;
  }

  this->CTest->AddSubmitFile(cmCTest::PartUpdate, "Update.xml");

  cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
                     "   Updating " << TypeToString(updateType)
                                    << " repository: " << source_dir << '\n',
                     args.Quiet);

  // Make sure VCS tool messages are in English so we can parse them.
  cmCLocaleEnvironmentScope fixLocale;
  static_cast<void>(fixLocale);

  // Create an object to interact with the VCS tool.
  std::unique_ptr<cmCTestVC> vc = MakeVC(updateType, this->CTest, &mf, ofs);

  vc->SetCommandLineTool(updateCommand);
  vc->SetSourceDirectory(source_dir);

  // Cleanup the working tree.
  vc->Cleanup();

  std::string start_time = this->CTest->CurrentTime();
  auto start_time_time = std::chrono::system_clock::now();
  auto elapsed_time_start = std::chrono::steady_clock::now();

  bool updated = vc->Update();
  std::string buildname =
    cmCTest::SafeBuildIdField(mf.GetSafeDefinition("CTEST_BUILD_NAME"));

  cmXMLWriter xml(os);
  xml.StartDocument();
  xml.StartElement("Update");
  xml.Attribute("mode", "Client");
  xml.Attribute("Generator",
                std::string("ctest-") + cmVersion::GetCMakeVersion());
  xml.Element("Site", mf.GetSafeDefinition("CTEST_SITE"));
  xml.Element("BuildName", buildname);
  xml.Element("BuildStamp",
              this->CTest->GetCurrentTag() + "-" +
                this->CTest->GetTestGroupString());
  xml.Element("StartDateTime", start_time);
  xml.Element("StartTime", start_time_time);
  xml.Element("UpdateCommand", vc->GetUpdateCommandLine());
  xml.Element("UpdateType", TypeToString(updateType));

  std::string changeId = mf.GetSafeDefinition("CTEST_CHANGE_ID");
  if (!changeId.empty()) {
    xml.Element("ChangeId", changeId);
  }

  bool loadedMods = vc->WriteXML(xml);

  int localModifications = 0;
  int numUpdated = vc->GetPathCount(cmCTestVC::PathUpdated);
  if (numUpdated) {
    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
                       "   Found " << numUpdated << " updated files\n",
                       args.Quiet);
  }
  if (int numModified = vc->GetPathCount(cmCTestVC::PathModified)) {
    cmCTestOptionalLog(
      this->CTest, HANDLER_OUTPUT,
      "   Found " << numModified << " locally modified files\n", args.Quiet);
    localModifications += numModified;
  }
  if (int numConflicting = vc->GetPathCount(cmCTestVC::PathConflicting)) {
    cmCTestOptionalLog(this->CTest, HANDLER_OUTPUT,
                       "   Found " << numConflicting << " conflicting files\n",
                       args.Quiet);
    localModifications += numConflicting;
  }

  cmCTestOptionalLog(this->CTest, DEBUG, "End" << std::endl, args.Quiet);
  std::string end_time = this->CTest->CurrentTime();
  xml.Element("EndDateTime", end_time);
  xml.Element("EndTime", std::chrono::system_clock::now());
  xml.Element("ElapsedMinutes",
              std::chrono::duration_cast<std::chrono::minutes>(
                std::chrono::steady_clock::now() - elapsed_time_start)
                .count());

  xml.StartElement("UpdateReturnStatus");
  if (localModifications) {
    xml.Content("Update error: "
                "There are modified or conflicting files in the repository");
    cmCTestLog(this->CTest, WARNING,
               "   There are modified or conflicting files in the repository"
                 << std::endl);
  }
  if (!updated) {
    xml.Content("Update command failed:\n");
    xml.Content(vc->GetUpdateCommandLine());
    cmCTestLog(this->CTest, HANDLER_OUTPUT,
               "   Update command failed: " << vc->GetUpdateCommandLine()
                                            << "\n");
  }
  xml.EndElement(); // UpdateReturnStatus
  xml.EndElement(); // Update
  xml.EndDocument();

  if (!args.ReturnValue.empty()) {
    mf.AddDefinition(args.ReturnValue,
                     std::to_string(updated && loadedMods ? numUpdated : -1));
  }

  return true;
}

bool cmCTestUpdateCommand::InitialPass(std::vector<std::string> const& args,
                                       cmExecutionStatus& status) const
{
  static auto const parser =
    cmArgumentParser<UpdateArguments>{ MakeBasicParser<UpdateArguments>() }
      .Bind("SOURCE"_s, &UpdateArguments::Source)
      .Bind("RETURN_VALUE"_s, &UpdateArguments::ReturnValue)
      .Bind("QUIET"_s, &UpdateArguments::Quiet);

  return this->Invoke(parser, args, status, [&](UpdateArguments& a) {
    return this->ExecuteUpdate(a, status);
  });
}
