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

#include <algorithm>
#include <cassert>
#include <cstddef>
#include <initializer_list>
#include <map>
#include <string>
#include <utility>

#include <cm/optional>
#include <cm/string_view>
#include <cm/type_traits>
#include <cmext/string_view>

#if !defined(_WIN32)
#  include <langinfo.h>
#endif

#include "cmsys/FStream.hxx"
#include "cmsys/Glob.hxx"
#include "cmsys/String.h"
#include "cmsys/SystemInformation.hxx"

#include "cmArgumentParser.h"
#include "cmExecutionStatus.h"
#include "cmList.h"
#include "cmMakefile.h"
#include "cmRange.h"
#include "cmStringAlgorithms.h"
#include "cmSystemTools.h"
#include "cmValue.h"
#include "cmWindowsRegistry.h"

#ifdef _WIN32
#  include "cmAlgorithms.h"
#  include "cmGlobalGenerator.h"
#  include "cmGlobalVisualStudio10Generator.h"
#  include "cmGlobalVisualStudioVersionedGenerator.h"
#  include "cmVSSetupHelper.h"
#endif

namespace {
std::string const DELIM[2] = { {}, ";" };

// BEGIN Private functions
template <typename T>
cm::enable_if_t<std::is_arithmetic<T>::value, std::string> ValueToString(
  T const& value)
{
  return std::to_string(value);
}

std::string ValueToString(char const* const value)
{
  return value ? value : std::string{};
}

std::string ValueToString(std::string const& value)
{
  return value;
}

cm::optional<std::string> GetValue(cmsys::SystemInformation& info,
                                   std::string const& key)
{
  if (key == "NUMBER_OF_LOGICAL_CORES"_s) {
    return ValueToString(info.GetNumberOfLogicalCPU());
  }
  if (key == "NUMBER_OF_PHYSICAL_CORES"_s) {
    return ValueToString(info.GetNumberOfPhysicalCPU());
  }
  if (key == "HOSTNAME"_s) {
    return ValueToString(info.GetHostname());
  }
  if (key == "FQDN"_s) {
    return ValueToString(info.GetFullyQualifiedDomainName());
  }
  if (key == "LOCALE_CHARSET"_s) {
#if defined(_WIN32)
    // On Windows we always use UTF-8.
    return ValueToString("UTF-8");
#else
    // On non-Windows platforms we use the locale's encoding.
    if (char const* charset = nl_langinfo(CODESET)) {
      if (cmsysString_strcasecmp(charset, "utf-8") == 0 ||
          cmsysString_strcasecmp(charset, "utf8") == 0) {
        charset = "UTF-8";
      }
      return ValueToString(charset);
    }
    return ValueToString("");
#endif
  }
  if (key == "TOTAL_VIRTUAL_MEMORY"_s) {
    return ValueToString(info.GetTotalVirtualMemory());
  }
  if (key == "AVAILABLE_VIRTUAL_MEMORY"_s) {
    return ValueToString(info.GetAvailableVirtualMemory());
  }
  if (key == "TOTAL_PHYSICAL_MEMORY"_s) {
    return ValueToString(info.GetTotalPhysicalMemory());
  }
  if (key == "AVAILABLE_PHYSICAL_MEMORY"_s) {
    return ValueToString(info.GetAvailablePhysicalMemory());
  }
  if (key == "IS_64BIT"_s) {
    return ValueToString(info.Is64Bits());
  }
  if (key == "HAS_FPU"_s) {
    return ValueToString(
      info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_FPU));
  }
  if (key == "HAS_MMX"_s) {
    return ValueToString(
      info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_MMX));
  }
  if (key == "HAS_MMX_PLUS"_s) {
    return ValueToString(info.DoesCPUSupportFeature(
      cmsys::SystemInformation::CPU_FEATURE_MMX_PLUS));
  }
  if (key == "HAS_SSE"_s) {
    return ValueToString(
      info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE));
  }
  if (key == "HAS_SSE2"_s) {
    return ValueToString(
      info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_SSE2));
  }
  if (key == "HAS_SSE_FP"_s) {
    return ValueToString(info.DoesCPUSupportFeature(
      cmsys::SystemInformation::CPU_FEATURE_SSE_FP));
  }
  if (key == "HAS_SSE_MMX"_s) {
    return ValueToString(info.DoesCPUSupportFeature(
      cmsys::SystemInformation::CPU_FEATURE_SSE_MMX));
  }
  if (key == "HAS_AMD_3DNOW"_s) {
    return ValueToString(info.DoesCPUSupportFeature(
      cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW));
  }
  if (key == "HAS_AMD_3DNOW_PLUS"_s) {
    return ValueToString(info.DoesCPUSupportFeature(
      cmsys::SystemInformation::CPU_FEATURE_AMD_3DNOW_PLUS));
  }
  if (key == "HAS_IA64"_s) {
    return ValueToString(
      info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_IA64));
  }
  if (key == "HAS_SERIAL_NUMBER"_s) {
    return ValueToString(info.DoesCPUSupportFeature(
      cmsys::SystemInformation::CPU_FEATURE_SERIALNUMBER));
  }
  if (key == "HAS_APIC"_s) {
    return ValueToString(
      info.DoesCPUSupportFeature(cmsys::SystemInformation::CPU_FEATURE_APIC));
  }
  if (key == "HAS_L1_CACHE"_s) {
    return ValueToString(info.DoesCPUSupportFeature(
      cmsys::SystemInformation::CPU_FEATURE_L1CACHE));
  }
  if (key == "PROCESSOR_NAME"_s) {
    return ValueToString(info.GetExtendedProcessorName());
  }
  if (key == "PROCESSOR_DESCRIPTION"_s) {
    return info.GetCPUDescription();
  }
  if (key == "PROCESSOR_SERIAL_NUMBER"_s) {
    return ValueToString(info.GetProcessorSerialNumber());
  }
  if (key == "OS_NAME"_s) {
    return ValueToString(info.GetOSName());
  }
  if (key == "OS_RELEASE"_s) {
    return ValueToString(info.GetOSRelease());
  }
  if (key == "OS_VERSION"_s) {
    return ValueToString(info.GetOSVersion());
  }
  if (key == "OS_PLATFORM"_s) {
    return ValueToString(info.GetOSPlatform());
  }
  if (key == "FAMILY_ID"_s) {
    return ValueToString(info.GetFamilyID());
  }
  if (key == "MODEL_ID"_s) {
    return ValueToString(info.GetModelID());
  }
  if (key == "MODEL_NAME"_s) {
    return ValueToString(info.GetModelName());
  }
  if (key == "PROCESSOR_APIC_ID"_s) {
    int apicId = info.GetProcessorAPICID();
    if (apicId) {
      return ValueToString(apicId);
    }
    return "";
  }
  if (key == "PROCESSOR_CACHE_SIZE"_s) {
    int cacheSize = info.GetProcessorCacheSize();
    if (cacheSize > 0) {
      return ValueToString(cacheSize);
    }
    return "";
  }
  if (key == "PROCESSOR_CLOCK_FREQUENCY"_s) {
    return ValueToString(info.GetProcessorClockFrequency());
  }
  if (key == "VENDOR_ID"_s) {
    return ValueToString(info.GetVendorID());
  }
  if (key == "VENDOR_STRING"_s) {
    return ValueToString(info.GetVendorString());
  }
  return {};
}

cm::optional<std::pair<std::string, std::string>> ParseOSReleaseLine(
  std::string const& line)
{
  std::string key;
  std::string value;

  char prev = 0;
  enum ParserState
  {
    PARSE_KEY_1ST,
    PARSE_KEY,
    FOUND_EQ,
    PARSE_SINGLE_QUOTE_VALUE,
    PARSE_DBL_QUOTE_VALUE,
    PARSE_VALUE,
    IGNORE_REST
  } state = PARSE_KEY_1ST;

  for (auto ch : line) {
    switch (state) {
      case PARSE_KEY_1ST:
        if (cmsysString_isalpha(ch) || ch == '_') {
          key += ch;
          state = PARSE_KEY;
        } else if (!cmsysString_isspace(ch)) {
          state = IGNORE_REST;
        }
        break;

      case PARSE_KEY:
        if (ch == '=') {
          state = FOUND_EQ;
        } else if (cmsysString_isalnum(ch) || ch == '_') {
          key += ch;
        } else {
          state = IGNORE_REST;
        }
        break;

      case FOUND_EQ:
        switch (ch) {
          case '\'':
            state = PARSE_SINGLE_QUOTE_VALUE;
            break;
          case '"':
            state = PARSE_DBL_QUOTE_VALUE;
            break;
          case '#':
          case '\\':
            state = IGNORE_REST;
            break;
          default:
            value += ch;
            state = PARSE_VALUE;
        }
        break;

      case PARSE_SINGLE_QUOTE_VALUE:
        if (ch == '\'') {
          if (prev != '\\') {
            state = IGNORE_REST;
          } else {
            assert(!value.empty());
            value[value.size() - 1] = ch;
          }
        } else {
          value += ch;
        }
        break;

      case PARSE_DBL_QUOTE_VALUE:
        if (ch == '"') {
          if (prev != '\\') {
            state = IGNORE_REST;
          } else {
            assert(!value.empty());
            value[value.size() - 1] = ch;
          }
        } else {
          value += ch;
        }
        break;

      case PARSE_VALUE:
        if (ch == '#' || cmsysString_isspace(ch)) {
          state = IGNORE_REST;
        } else {
          value += ch;
        }
        break;

      default:
        // Unexpected os-release parser state!
        state = IGNORE_REST;
        break;
    }

    if (state == IGNORE_REST) {
      break;
    }
    prev = ch;
  }
  if (!(key.empty() || value.empty())) {
    return std::make_pair(key, value);
  }
  return {};
}

std::map<std::string, std::string> GetOSReleaseVariables(
  cmExecutionStatus& status)
{
  auto& makefile = status.GetMakefile();
  auto const& sysroot = makefile.GetSafeDefinition("CMAKE_SYSROOT");

  std::map<std::string, std::string> data;
  // Based on
  // https://www.freedesktop.org/software/systemd/man/latest/os-release.html
  for (auto name : { "/etc/os-release"_s, "/usr/lib/os-release"_s }) {
    auto const& filename = cmStrCat(sysroot, name);
    if (cmSystemTools::FileExists(filename)) {
      cmsys::ifstream fin(filename.c_str());
      for (std::string line; !std::getline(fin, line).fail();) {
        auto kv = ParseOSReleaseLine(line);
        if (kv.has_value()) {
          data.emplace(kv.value());
        }
      }
      break;
    }
  }
  // Got smth?
  if (!data.empty()) {
    return data;
  }

  // Ugh, it could be some pre-os-release distro.
  // Lets try some fallback getters.
  // See also:
  //  - http://linuxmafia.com/faq/Admin/release-files.html

  // 1. CMake provided
  cmsys::Glob gl;
  std::vector<std::string> scripts;
  auto const findExpr = cmStrCat(cmSystemTools::GetCMakeRoot(),
                                 "/Modules/Internal/OSRelease/*.cmake");
  if (gl.FindFiles(findExpr)) {
    scripts = gl.GetFiles();
  }

  // 2. User provided (append to the CMake provided)
  cmList::append(
    scripts, makefile.GetDefinition("CMAKE_GET_OS_RELEASE_FALLBACK_SCRIPTS"));

  // Filter out files that are not in format `NNN-name.cmake`
  auto checkName = [](std::string const& filepath) -> bool {
    auto const& filename = cmSystemTools::GetFilenameName(filepath);
    // NOTE Minimum filename length expected:
    //   NNN-<at-least-one-char-name>.cmake  --> 11
    return (filename.size() < 11) || !cmsysString_isdigit(filename[0]) ||
      !cmsysString_isdigit(filename[1]) || !cmsysString_isdigit(filename[2]) ||
      filename[3] != '-';
  };
  scripts.erase(std::remove_if(scripts.begin(), scripts.end(), checkName),
                scripts.end());

  // Make sure scripts are running in desired order
  std::sort(scripts.begin(), scripts.end(),
            [](std::string const& lhs, std::string const& rhs) -> bool {
              long lhs_order;
              cmStrToLong(cmSystemTools::GetFilenameName(lhs).substr(0u, 3u),
                          &lhs_order);
              long rhs_order;
              cmStrToLong(cmSystemTools::GetFilenameName(rhs).substr(0u, 3u),
                          &rhs_order);
              return lhs_order < rhs_order;
            });

  // Name of the variable to put the results
  std::string const result_variable{ "CMAKE_GET_OS_RELEASE_FALLBACK_RESULT" };

  for (auto const& script : scripts) {
    // Unset the result variable
    makefile.RemoveDefinition(result_variable);

    // include FATAL_ERROR and ERROR in the return status
    if (!makefile.ReadListFile(script) ||
        cmSystemTools::GetErrorOccurredFlag()) {
      // Ok, no worries... go try the next script.
      continue;
    }

    cmList variables{ makefile.GetDefinition(result_variable) };
    if (variables.empty()) {
      // Heh, this script didn't found anything... go try the next one.
      continue;
    }

    for (auto const& variable : variables) {
      auto value = makefile.GetSafeDefinition(variable);
      makefile.RemoveDefinition(variable);

      if (!cmHasPrefix(variable, cmStrCat(result_variable, '_'))) {
        // Ignore unknown variable set by the script
        continue;
      }

      auto key = variable.substr(result_variable.size() + 1,
                                 variable.size() - result_variable.size() - 1);
      data.emplace(std::move(key), std::move(value));
    }

    // Try 'till some script can get anything
    if (!data.empty()) {
      data.emplace("USED_FALLBACK_SCRIPT", script);
      break;
    }
  }

  makefile.RemoveDefinition(result_variable);

  return data;
}

cm::optional<std::string> GetDistribValue(cmExecutionStatus& status,
                                          std::string const& key,
                                          std::string const& variable)
{
  auto const prefix = "DISTRIB_"_s;
  if (!cmHasPrefix(key, prefix)) {
    return {};
  }

  static std::map<std::string, std::string> const s_os_release =
    GetOSReleaseVariables(status);

  auto& makefile = status.GetMakefile();

  std::string const subkey =
    key.substr(prefix.size(), key.size() - prefix.size());
  if (subkey == "INFO"_s) {
    std::string vars;
    for (auto const& kv : s_os_release) {
      auto cmake_var_name = cmStrCat(variable, '_', kv.first);
      vars += DELIM[!vars.empty()] + cmake_var_name;
      makefile.AddDefinition(cmake_var_name, kv.second);
    }
    return cm::optional<std::string>(std::move(vars));
  }

  // Query individual variable
  auto const it = s_os_release.find(subkey);
  if (it != s_os_release.cend()) {
    return it->second;
  }

  // NOTE Empty string means requested variable not set
  return std::string{};
}

#ifdef _WIN32
std::string FindMSYSTEM_PREFIX(std::vector<std::string> prefixes)
{
  for (std::string const& prefix : prefixes) {
    std::string out;
    std::string err;
    int ret;
    // In a modern MSYSTEM environment we expect cygpath to be in PATH.
    std::vector<std::string> cygpath_cmd{ "cygpath", "-w", prefix };
    if (cmSystemTools::RunSingleCommand(cygpath_cmd, &out, &err, &ret, nullptr,
                                        cmSystemTools::OUTPUT_NONE)) {
      if (ret == 0) {
        out = cmTrimWhitespace(out);
        cmSystemTools::ConvertToUnixSlashes(out);
        if (cmSystemTools::FileIsDirectory(out)) {
          return out;
        }
      }
    } else {
      // In a legacy MSYSTEM environment (MinGW/MSYS 1.0) there is no
      // cygpath but we expect 'sh' to be in PATH.
      std::vector<std::string> sh_cmd{
        "sh", "-c", cmStrCat("cd \"", prefix, "\" && cmd //c cd")
      };
      if (cmSystemTools::RunSingleCommand(sh_cmd, &out, &err, &ret, nullptr,
                                          cmSystemTools::OUTPUT_NONE)) {
        if (ret == 0) {
          out = cmTrimWhitespace(out);
          cmSystemTools::ConvertToUnixSlashes(out);
          if (cmSystemTools::FileIsDirectory(out)) {
            return out;
          }
        }
      }
    }
  }
  return {};
}

std::string FallbackMSYSTEM_PREFIX(cm::string_view msystem)
{
  // These layouts are used by distributions such as
  // * MSYS2: https://www.msys2.org/docs/environments/
  // * MinGW/MSYS 1.0: http://mingw.osdn.io/
  if (msystem == "MSYS"_s) {
    static std::string const msystem_msys = FindMSYSTEM_PREFIX({ "/usr" });
    return msystem_msys;
  }
  if (msystem == "MINGW32"_s) {
    static std::string const msystem_mingw32 =
      FindMSYSTEM_PREFIX({ "/mingw32", "/mingw" });
    return msystem_mingw32;
  }
  if (msystem == "MINGW64"_s) {
    static std::string const msystem_mingw64 =
      FindMSYSTEM_PREFIX({ "/mingw64" });
    return msystem_mingw64;
  }
  if (msystem == "UCRT64"_s) {
    static std::string const msystem_ucrt64 =
      FindMSYSTEM_PREFIX({ "/ucrt64" });
    return msystem_ucrt64;
  }
  if (msystem == "CLANG32"_s) {
    static std::string const msystem_clang32 =
      FindMSYSTEM_PREFIX({ "/clang32" });
    return msystem_clang32;
  }
  if (msystem == "CLANG64"_s) {
    static std::string const msystem_clang64 =
      FindMSYSTEM_PREFIX({ "/clang64" });
    return msystem_clang64;
  }
  if (msystem == "CLANGARM64"_s) {
    static std::string const msystem_clangarm64 =
      FindMSYSTEM_PREFIX({ "/clangarm64" });
    return msystem_clangarm64;
  }
  return {};
}

cm::optional<std::string> GetWindowsValue(cmExecutionStatus& status,
                                          std::string const& key)
{
  auto* const gg = status.GetMakefile().GetGlobalGenerator();
  for (auto vs : { 15, 16, 17, 18 }) {
    if (key == cmStrCat("VS_"_s, vs, "_DIR"_s)) {
      std::string value;
      // If generating for the VS nn IDE, use the same instance.

      if (cmHasPrefix(gg->GetName(), cmStrCat("Visual Studio "_s, vs, ' '))) {
        cmGlobalVisualStudioVersionedGenerator* vsNNgen =
          static_cast<cmGlobalVisualStudioVersionedGenerator*>(gg);
        if (vsNNgen->GetVSInstance(value)) {
          return value;
        }
      }

      // Otherwise, find a VS nn instance ourselves.
      cmVSSetupAPIHelper vsSetupAPIHelper(vs);
      if (vsSetupAPIHelper.GetVSInstanceInfo(value)) {
        cmSystemTools::ConvertToUnixSlashes(value);
      }
      return value;
    }
  }

  if (key == "VS_MSBUILD_COMMAND"_s && gg->IsVisualStudioAtLeast10()) {
    cmGlobalVisualStudio10Generator* vs10gen =
      static_cast<cmGlobalVisualStudio10Generator*>(gg);
    return vs10gen->FindMSBuildCommandEarly(&status.GetMakefile());
  }

  if (key == "MSYSTEM_PREFIX") {
    // MSYSTEM_PREFIX is meaningful only under a MSYSTEM environment.
    cm::optional<std::string> ms = cmSystemTools::GetEnvVar("MSYSTEM");
    if (!ms || ms->empty()) {
      return std::string();
    }
    // Prefer the MSYSTEM_PREFIX environment variable.
    if (cm::optional<std::string> msp =
          cmSystemTools::GetEnvVar("MSYSTEM_PREFIX")) {
      cmSystemTools::ConvertToUnixSlashes(*msp);
      if (cmSystemTools::FileIsDirectory(*msp)) {
        return msp;
      }
    }
    // Fall back to known distribution layouts.
    return FallbackMSYSTEM_PREFIX(*ms);
  }
  return {};
}
#endif

cm::optional<std::string> GetValueChained()
{
  return {};
}

template <typename GetterFn, typename... Next>
cm::optional<std::string> GetValueChained(GetterFn current, Next... chain)
{
  auto value = current();
  if (value.has_value()) {
    return value;
  }
  return GetValueChained(chain...);
}

template <typename Range>
bool QueryWindowsRegistry(Range args, cmExecutionStatus& status,
                          std::string const& variable)
{
  using View = cmWindowsRegistry::View;
  if (args.empty()) {
    status.SetError("missing <key> specification.");
    return false;
  }
  std::string const& key = *args.begin();

  struct Arguments : public ArgumentParser::ParseResult
  {
    std::string ValueName;
    bool ValueNames = false;
    bool SubKeys = false;
    std::string View;
    std::string Separator;
    std::string ErrorVariable;
  };
  cmArgumentParser<Arguments> parser;
  parser.Bind("VALUE"_s, &Arguments::ValueName)
    .Bind("VALUE_NAMES"_s, &Arguments::ValueNames)
    .Bind("SUBKEYS"_s, &Arguments::SubKeys)
    .Bind("VIEW"_s, &Arguments::View)
    .Bind("SEPARATOR"_s, &Arguments::Separator)
    .Bind("ERROR_VARIABLE"_s, &Arguments::ErrorVariable);
  std::vector<std::string> invalidArgs;

  Arguments const arguments = parser.Parse(args.advance(1), &invalidArgs);
  if (!invalidArgs.empty()) {
    status.SetError(cmStrCat("given invalid argument(s) \"",
                             cmJoin(invalidArgs, ", "_s), "\"."));
    return false;
  }
  if (arguments.MaybeReportError(status.GetMakefile())) {
    return true;
  }
  if ((!arguments.ValueName.empty() &&
       (arguments.ValueNames || arguments.SubKeys)) ||
      (arguments.ValueName.empty() && arguments.ValueNames &&
       arguments.SubKeys)) {
    status.SetError("given mutually exclusive sub-options VALUE, "
                    "VALUE_NAMES or SUBKEYS.");
    return false;
  }

  if (!arguments.View.empty() && !cmWindowsRegistry::ToView(arguments.View)) {
    status.SetError(
      cmStrCat("given invalid value for VIEW: ", arguments.View, '.'));
    return false;
  }

  auto& makefile = status.GetMakefile();

  makefile.AddDefinition(variable, ""_s);

  auto view = arguments.View.empty()
    ? View::Both
    : *cmWindowsRegistry::ToView(arguments.View);
  cmWindowsRegistry registry(makefile);
  if (arguments.ValueNames) {
    auto result = registry.GetValueNames(key, view);
    if (result) {
      makefile.AddDefinition(variable, cmList::to_string(*result));
    }
  } else if (arguments.SubKeys) {
    auto result = registry.GetSubKeys(key, view);
    if (result) {
      makefile.AddDefinition(variable, cmList::to_string(*result));
    }
  } else {
    auto result =
      registry.ReadValue(key, arguments.ValueName, view, arguments.Separator);
    if (result) {
      makefile.AddDefinition(variable, *result);
    }
  }

  // return error message if requested
  if (!arguments.ErrorVariable.empty()) {
    makefile.AddDefinition(arguments.ErrorVariable, registry.GetLastError());
  }

  return true;
}

// END Private functions
} // anonymous namespace

// cmCMakeHostSystemInformation
bool cmCMakeHostSystemInformationCommand(std::vector<std::string> const& args,
                                         cmExecutionStatus& status)
{
  std::size_t current_index = 0;

  if (args.size() < (current_index + 2) || args[current_index] != "RESULT"_s) {
    status.SetError("missing RESULT specification.");
    return false;
  }

  auto const& variable = args[current_index + 1];
  current_index += 2;

  if (args.size() < (current_index + 2) || args[current_index] != "QUERY"_s) {
    status.SetError("missing QUERY specification");
    return false;
  }

  if (args[current_index + 1] == "WINDOWS_REGISTRY"_s) {
    return QueryWindowsRegistry(cmMakeRange(args).advance(current_index + 2),
                                status, variable);
  }

  static cmsys::SystemInformation info;
  static auto initialized = false;
  if (!initialized) {
    info.RunCPUCheck();
    info.RunOSCheck();
    info.RunMemoryCheck();
    initialized = true;
  }

  std::string result_list;
  for (auto i = current_index + 1; i < args.size(); ++i) {
    result_list += DELIM[!result_list.empty()];

    auto const& key = args[i];
    // clang-format off
    auto value =
      GetValueChained(
          [&]() { return GetValue(info, key); }
        , [&]() { return GetDistribValue(status, key, variable); }
#ifdef _WIN32
        , [&]() { return GetWindowsValue(status, key); }
#endif
        );
    // clang-format on
    if (!value) {
      status.SetError("does not recognize <key> " + key);
      return false;
    }
    result_list += value.value();
  }

  status.GetMakefile().AddDefinition(variable, result_list);

  return true;
}
