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

#include <sstream>

#include "cmsys/FStream.hxx"

#include "cmGeneratedFileStream.h"
#include "cmListFileCache.h"
#include "cmMessageType.h"
#include "cmMessenger.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"

bool cmGlobVerificationManager::SaveVerificationScript(const std::string& path,
                                                       cmMessenger* messenger)
{
  if (this->Cache.empty()) {
    return true;
  }

  std::string scriptFile = cmStrCat(path, "/CMakeFiles");
  std::string stampFile = scriptFile;
  cmSystemTools::MakeDirectory(scriptFile);
  scriptFile += "/VerifyGlobs.cmake";
  stampFile += "/cmake.verify_globs";
  cmGeneratedFileStream verifyScriptFile(scriptFile);
  verifyScriptFile.SetCopyIfDifferent(true);
  if (!verifyScriptFile) {
    cmSystemTools::Error("Unable to open verification script file for save. " +
                         scriptFile);
    cmSystemTools::ReportLastSystemError("");
    return false;
  }

  verifyScriptFile << std::boolalpha;
  verifyScriptFile << "# CMAKE generated file: DO NOT EDIT!\n"
                   << "# Generated by CMake Version "
                   << cmVersion::GetMajorVersion() << "."
                   << cmVersion::GetMinorVersion() << "\n";

  verifyScriptFile << "cmake_policy(SET CMP0009 NEW)\n";

  for (auto const& i : this->Cache) {
    CacheEntryKey k = std::get<0>(i);
    CacheEntryValue v = std::get<1>(i);

    if (!v.Initialized) {
      continue;
    }

    verifyScriptFile << "\n";

    for (auto const& bt : v.Backtraces) {
      verifyScriptFile << "# " << std::get<0>(bt);
      messenger->PrintBacktraceTitle(verifyScriptFile, std::get<1>(bt));
      verifyScriptFile << "\n";
    }

    k.PrintGlobCommand(verifyScriptFile, "NEW_GLOB");
    verifyScriptFile << "\n";

    verifyScriptFile << "set(OLD_GLOB\n";
    for (const std::string& file : v.Files) {
      verifyScriptFile << "  \"" << file << "\"\n";
    }
    verifyScriptFile << "  )\n";

    verifyScriptFile << "if(NOT \"${NEW_GLOB}\" STREQUAL \"${OLD_GLOB}\")\n"
                     << "  message(\"-- GLOB mismatch!\")\n"
                     << "  file(TOUCH_NOCREATE \"" << stampFile << "\")\n"
                     << "endif()\n";
  }
  verifyScriptFile.Close();

  cmsys::ofstream verifyStampFile(stampFile.c_str());
  if (!verifyStampFile) {
    cmSystemTools::Error("Unable to open verification stamp file for write. " +
                         stampFile);
    return false;
  }
  verifyStampFile << "# This file is generated by CMake for checking of the "
                     "VerifyGlobs.cmake file\n";
  this->VerifyScript = scriptFile;
  this->VerifyStamp = stampFile;
  return true;
}

bool cmGlobVerificationManager::DoWriteVerifyTarget() const
{
  return !this->VerifyScript.empty() && !this->VerifyStamp.empty();
}

bool cmGlobVerificationManager::CacheEntryKey::operator<(
  const CacheEntryKey& r) const
{
  if (this->Recurse < r.Recurse) {
    return true;
  }
  if (this->Recurse > r.Recurse) {
    return false;
  }
  if (this->ListDirectories < r.ListDirectories) {
    return true;
  }
  if (this->ListDirectories > r.ListDirectories) {
    return false;
  }
  if (this->FollowSymlinks < r.FollowSymlinks) {
    return true;
  }
  if (this->FollowSymlinks > r.FollowSymlinks) {
    return false;
  }
  if (this->Relative < r.Relative) {
    return true;
  }
  if (this->Relative > r.Relative) {
    return false;
  }
  if (this->Expression < r.Expression) {
    return true;
  }
  if (this->Expression > r.Expression) {
    return false;
  }
  return false;
}

void cmGlobVerificationManager::CacheEntryKey::PrintGlobCommand(
  std::ostream& out, const std::string& cmdVar)
{
  out << "file(GLOB" << (this->Recurse ? "_RECURSE " : " ");
  out << cmdVar << " ";
  if (this->Recurse && this->FollowSymlinks) {
    out << "FOLLOW_SYMLINKS ";
  }
  out << "LIST_DIRECTORIES " << this->ListDirectories << " ";
  if (!this->Relative.empty()) {
    out << "RELATIVE \"" << this->Relative << "\" ";
  }
  out << "\"" << this->Expression << "\")";
}

void cmGlobVerificationManager::AddCacheEntry(
  const bool recurse, const bool listDirectories, const bool followSymlinks,
  const std::string& relative, const std::string& expression,
  const std::vector<std::string>& files, const std::string& variable,
  const cmListFileBacktrace& backtrace, cmMessenger* messenger)
{
  CacheEntryKey key = CacheEntryKey(recurse, listDirectories, followSymlinks,
                                    relative, expression);
  CacheEntryValue& value = this->Cache[key];
  if (!value.Initialized) {
    value.Files = files;
    value.Initialized = true;
    value.Backtraces.emplace_back(variable, backtrace);
  } else if (value.Initialized && value.Files != files) {
    std::ostringstream message;
    message << std::boolalpha;
    message << "The glob expression\n ";
    key.PrintGlobCommand(message, variable);
    message << "\nwas already present in the glob cache but the directory "
               "contents have changed during the configuration run.\n";
    message << "Matching glob expressions:";
    for (auto const& bt : value.Backtraces) {
      message << "\n  " << std::get<0>(bt);
      messenger->PrintBacktraceTitle(message, std::get<1>(bt));
    }
    messenger->IssueMessage(MessageType::FATAL_ERROR, message.str(),
                            backtrace);
  } else {
    value.Backtraces.emplace_back(variable, backtrace);
  }
}

void cmGlobVerificationManager::Reset()
{
  this->Cache.clear();
  this->VerifyScript.clear();
  this->VerifyStamp.clear();
}
