/* 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.");
  }

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

  // 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);
      }
    }
  }
}
