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

#include <set>

#include "cmsys/FStream.hxx"

#include "cmExecutionStatus.h"
#include "cmMakefile.h"
#include "cmStateTypes.h"
#include "cmSystemTools.h"
#include "cmake.h"

static bool ReadWithPrefix(std::vector<std::string> const& args,
                           cmExecutionStatus& status);

static void CheckLine(cmMakefile& mf, std::string const& prefix,
                      std::set<std::string> const& variablesToRead,
                      const char* line);

bool cmLoadCacheCommand(std::vector<std::string> const& args,
                        cmExecutionStatus& status)
{
  if (args.empty()) {
    status.SetError("called with wrong number of arguments.");
    return false;
  }

  if (args.size() >= 2 && args[1] == "READ_WITH_PREFIX") {
    return ReadWithPrefix(args, status);
  }

  if (status.GetMakefile().GetCMakeInstance()->GetWorkingMode() ==
      cmake::SCRIPT_MODE) {
    status.SetError(
      "Only load_cache(READ_WITH_PREFIX) may be used in script mode");
    return false;
  }

  // Cache entries to be excluded from the import list.
  // If this set is empty, all cache entries are brought in
  // and they can not be overridden.
  bool excludeFiles = false;
  std::set<std::string> excludes;

  for (std::string const& arg : args) {
    if (excludeFiles) {
      excludes.insert(arg);
    }
    if (arg == "EXCLUDE") {
      excludeFiles = true;
    }
    if (excludeFiles && (arg == "INCLUDE_INTERNALS")) {
      break;
    }
  }

  // Internal cache entries to be imported.
  // If this set is empty, no internal cache entries are
  // brought in.
  bool includeFiles = false;
  std::set<std::string> includes;

  for (std::string const& arg : args) {
    if (includeFiles) {
      includes.insert(arg);
    }
    if (arg == "INCLUDE_INTERNALS") {
      includeFiles = true;
    }
    if (includeFiles && (arg == "EXCLUDE")) {
      break;
    }
  }

  cmMakefile& mf = status.GetMakefile();

  // Loop over each build directory listed in the arguments.  Each
  // directory has a cache file.
  for (std::string const& arg : args) {
    if ((arg == "EXCLUDE") || (arg == "INCLUDE_INTERNALS")) {
      break;
    }
    mf.GetCMakeInstance()->LoadCache(arg, false, excludes, includes);
  }

  return true;
}

static bool ReadWithPrefix(std::vector<std::string> const& args,
                           cmExecutionStatus& status)
{
  // Make sure we have a prefix.
  if (args.size() < 3) {
    status.SetError("READ_WITH_PREFIX form must specify a prefix.");
    return false;
  }

  // Make sure the cache file exists.
  std::string cacheFile = args[0] + "/CMakeCache.txt";
  if (!cmSystemTools::FileExists(cacheFile)) {
    std::string e = "Cannot load cache file from " + cacheFile;
    status.SetError(e);
    return false;
  }

  // Prepare the table of variables to read.
  std::string const& prefix = args[2];
  std::set<std::string> const variablesToRead(args.begin() + 3, args.end());

  // Read the cache file.
  cmsys::ifstream fin(cacheFile.c_str());

  cmMakefile& mf = status.GetMakefile();

  // This is a big hack read loop to overcome a buggy ifstream
  // implementation on HP-UX.  This should work on all platforms even
  // for small buffer sizes.
  const int bufferSize = 4096;
  char buffer[bufferSize];
  std::string line;
  while (fin) {
    // Read a block of the file.
    fin.read(buffer, bufferSize);
    if (fin.gcount()) {
      // Parse for newlines directly.
      const char* i = buffer;
      const char* end = buffer + fin.gcount();
      while (i != end) {
        const char* begin = i;
        while (i != end && *i != '\n') {
          ++i;
        }
        if (i == begin || *(i - 1) != '\r') {
          // Include this portion of the line.
          line += std::string(begin, i - begin);
        } else {
          // Include this portion of the line.
          // Don't include the \r in a \r\n pair.
          line += std::string(begin, i - 1 - begin);
        }
        if (i != end) {
          // Completed a line.
          CheckLine(mf, prefix, variablesToRead, line.c_str());
          line.clear();

          // Skip the newline character.
          ++i;
        }
      }
    }
  }
  if (!line.empty()) {
    // Partial last line.
    CheckLine(mf, prefix, variablesToRead, line.c_str());
  }

  return true;
}

static void CheckLine(cmMakefile& mf, std::string const& prefix,
                      std::set<std::string> const& variablesToRead,
                      const char* line)
{
  // Check one line of the cache file.
  std::string var;
  std::string value;
  cmStateEnums::CacheEntryType type = cmStateEnums::UNINITIALIZED;
  if (cmake::ParseCacheEntry(line, var, value, type)) {
    // Found a real entry.  See if this one was requested.
    if (variablesToRead.find(var) != variablesToRead.end()) {
      // This was requested.  Set this variable locally with the given
      // prefix.
      var = prefix + var;
      if (!value.empty()) {
        mf.AddDefinition(var, value);
      } else {
        mf.RemoveDefinition(var);
      }
    }
  }
}
