/* 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 "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmVersion.h"

bool cmGlobVerificationManager::SaveVerificationScript(const std::string& path)
{
  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);
      std::get<1>(bt).PrintTitle(verifyScriptFile);
      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)
{
  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);
    backtrace.PrintTitle(message);
    message << "\nwas already present in the glob cache but the directory\n"
               "contents have changed during the configuration run.\n";
    message << "Matching glob expressions:";
    for (auto const& bt : value.Backtraces) {
      message << "\n  " << std::get<0>(bt);
      std::get<1>(bt).PrintTitle(message);
    }
    cmSystemTools::Error(message.str());
  } else {
    value.Backtraces.emplace_back(variable, backtrace);
  }
}

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