<commit_before>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author <NAME>
////////////////////////////////////////////////////////////////////////////////

#include "Rest/Version.h"

#ifdef _WIN32
#include "Basics/win-utils.h"
#endif

#include <openssl/ssl.h>
#include <sstream>

#include <velocypack/Builder.h>
#include <velocypack/Version.h>
#include <velocypack/velocypack-aliases.h>

#include "Basics/StringUtils.h"
#include "Basics/Utf8Helper.h"
#include "Basics/build-date.h"
#include "Basics/conversions.h"
#include "Basics/json.h"

using namespace arangodb::rest;

////////////////////////////////////////////////////////////////////////////////
/// @brief initialize
////////////////////////////////////////////////////////////////////////////////

void Version::initialize() {
  if (!Values.empty()) {
    return;
  }

  Values["architecture"] = (sizeof(void*) == 4 ? "32" : "64") + std::string("bit");
  Values["assembler-crc32"] = (ENABLE_ASM_CRC32) ? "true" : "false";
  Values["boost-version"] = getBoostVersion();
  Values["build-date"] = getBuildDate();
  Values["fd-setsize"] = arangodb::basics::StringUtils::itoa(FD_SETSIZE);
  Values["icu-version"] = getICUVersion();
  Values["libev-version"] = getLibevVersion();
  Values["openssl-version"] = getOpenSSLVersion();
  Values["repository-version"] = getRepositoryVersion();
  Values["server-version"] = getServerVersion();
  Values["sizeof int"] = arangodb::basics::StringUtils::itoa(sizeof(int));
  Values["sizeof void*"] = arangodb::basics::StringUtils::itoa(sizeof(void*));
  Values["v8-version"] = getV8Version();
  Values["vpack-version"] = getVPackVersion();
  Values["zlib-version"] = getZLibVersion();

#if defined(__SSE4_2__) && !defined(NO_SSE42)
  Values["sse4_2"] = "true";
#else
  Values["sse4_2"] = "true";
#endif

#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
  Values["maintainer-mode"] = "true";
#else
  Values["maintainer-mode"] = "false";
#endif

#ifdef TRI_HAVE_TCMALLOC
  Values["tcmalloc"] = "true";
#else
  Values["tcmalloc"] = "false";
#endif

#ifdef TRI_HAVE_POLL_H
  Values["fd-client-event-handler"] = "poll";
#else
  Values["fd-client-event-handler"] = "select";
#endif

  for (auto& it : Values) {
    arangodb::basics::StringUtils::trimInPlace(it.second);
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get numeric server version
////////////////////////////////////////////////////////////////////////////////

int32_t Version::getNumericServerVersion() {
  char const* apiVersion = ARANGODB_VERSION;
  char const* p = apiVersion;

  // read major version
  while (*p >= '0' && *p <= '9') {
    ++p;
  }

  TRI_ASSERT(*p == '.');
  int32_t major = TRI_Int32String2(apiVersion, (p - apiVersion));

  apiVersion = ++p;

  // read minor version
  while (*p >= '0' && *p <= '9') {
    ++p;
  }

  TRI_ASSERT((*p == '.' || *p == '-' || *p == '\0') && p != apiVersion);
  int32_t minor = TRI_Int32String2(apiVersion, (p - apiVersion));

  return (int32_t)(minor * 100L + major * 10000L);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get server version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getServerVersion() { return std::string(ARANGODB_VERSION); }

////////////////////////////////////////////////////////////////////////////////
/// @brief get BOOST version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getBoostVersion() {
#ifdef ARANGODB_BOOST_VERSION
  return std::string(ARANGODB_BOOST_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get V8 version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getV8Version() {
#ifdef ARANGODB_V8_VERSION
  return std::string(ARANGODB_V8_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get OpenSSL version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getOpenSSLVersion() {
#ifdef OPENSSL_VERSION_TEXT
  return std::string(OPENSSL_VERSION_TEXT);
#elif defined(ARANGODB_OPENSSL_VERSION)
  return std::string(ARANGODB_OPENSSL_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get libev version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getLibevVersion() {
#ifdef ARANGODB_LIBEV_VERSION
  return std::string(ARANGODB_LIBEV_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get vpack version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getVPackVersion() {
  return arangodb::velocypack::Version::BuildVersion.toString();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get zlib version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getZLibVersion() {
#ifdef ARANGODB_ZLIB_VERSION
  return std::string(ARANGODB_ZLIB_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get ICU version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getICUVersion() {
  UVersionInfo icuVersion;
  char icuVersionString[U_MAX_VERSION_STRING_LENGTH];
  u_getVersion(icuVersion);
  u_versionToString(icuVersion, icuVersionString);

  return icuVersionString;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get repository version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getRepositoryVersion() {
#ifdef TRI_REPOSITORY_VERSION
  return std::string(TRI_REPOSITORY_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get build date
////////////////////////////////////////////////////////////////////////////////

std::string Version::getBuildDate() {
// the OpenSuSE build system does not like it, if __DATE__ is used
#ifdef ARANGODB_BUILD_DATE
  return std::string(ARANGODB_BUILD_DATE);
#else
  return std::string(__DATE__).append(" ").append(__TIME__);
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return a server version string
////////////////////////////////////////////////////////////////////////////////

std::string Version::getVerboseVersionString() {
  std::ostringstream version;

  version << "ArangoDB " << ARANGODB_VERSION_FULL << " "
          << (sizeof(void*) == 4 ? "32" : "64") << "bit"
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
          << " maintainer mode"
#endif
          << ", using "
#ifdef TRI_HAVE_TCMALLOC
          << "tcmalloc, "
#endif
          << "VPack " << getVPackVersion() << ", "
          << "ICU " << getICUVersion() << ", "
          << "V8 " << getV8Version() << ", " << getOpenSSLVersion();

  return version.str();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get detailed version information as a (multi-line) string
////////////////////////////////////////////////////////////////////////////////

std::string Version::getDetailed() {
  std::string result;

  for (auto& it : Values) {
    std::string const& value = it.second;

    if (!value.empty()) {
      result.append(it.first);
      result.append(": ");
      result.append(it.second);
#ifdef _WIN32
      result += "\r\n";
#else
      result += "\n";
#endif
    }
  }

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief JSONize all data
////////////////////////////////////////////////////////////////////////////////

void Version::getJson(TRI_memory_zone_t* zone, TRI_json_t* dst) {
  for (auto const& it : Values) {
    std::string const& value = it.second;

    if (!value.empty()) {
      std::string const& key = it.first;

      TRI_Insert3ObjectJson(
          zone, dst, key.c_str(),
          TRI_CreateStringCopyJson(zone, value.c_str(), value.size()));
    }
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief VelocyPack all data
////////////////////////////////////////////////////////////////////////////////

void Version::getVPack(VPackBuilder& dst) {
  for (auto const& it : Values) {
    std::string const& value = it.second;

    if (!value.empty()) {
      dst.add(it.first, VPackValue(value));
    }
  }
}

std::map<std::string, std::string> Version::Values;
<commit_msg>add more version information<commit_after>////////////////////////////////////////////////////////////////////////////////
/// DISCLAIMER
///
/// Copyright 2014-2016 ArangoDB GmbH, Cologne, Germany
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
///     http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
///
/// @author <NAME>
////////////////////////////////////////////////////////////////////////////////

#include "Rest/Version.h"

#ifdef _WIN32
#include "Basics/win-utils.h"
#endif

#include <openssl/ssl.h>
#include <sstream>

#include <velocypack/Builder.h>
#include <velocypack/Version.h>
#include <velocypack/velocypack-aliases.h>

#include "Basics/StringUtils.h"
#include "Basics/Utf8Helper.h"
#include "Basics/build-date.h"
#include "Basics/conversions.h"
#include "Basics/json.h"

using namespace arangodb::rest;

////////////////////////////////////////////////////////////////////////////////
/// @brief initialize
////////////////////////////////////////////////////////////////////////////////

void Version::initialize() {
  if (!Values.empty()) {
    return;
  }

  Values["architecture"] = (sizeof(void*) == 4 ? "32" : "64") + std::string("bit");
  Values["asm-crc32"] = (ENABLE_ASM_CRC32) ? "true" : "false";
  Values["boost-version"] = getBoostVersion();
  Values["build-date"] = getBuildDate();
  Values["fd-setsize"] = arangodb::basics::StringUtils::itoa(FD_SETSIZE);
  Values["icu-version"] = getICUVersion();
  Values["libev-version"] = getLibevVersion();
  Values["openssl-version"] = getOpenSSLVersion();
  Values["repository-version"] = getRepositoryVersion();
  Values["server-version"] = getServerVersion();
  Values["sizeof int"] = arangodb::basics::StringUtils::itoa(sizeof(int));
  Values["sizeof void*"] = arangodb::basics::StringUtils::itoa(sizeof(void*));
  Values["v8-version"] = getV8Version();
  Values["vpack-version"] = getVPackVersion();
  Values["zlib-version"] = getZLibVersion();

#if defined(__SSE4_2__) && !defined(NO_SSE42)
  Values["sse42"] = "true";
#else
  Values["sse42"] = "false";
#endif

#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
  Values["maintainer-mode"] = "true";
#else
  Values["maintainer-mode"] = "false";
#endif

#ifdef TRI_HAVE_TCMALLOC
  Values["tcmalloc"] = "true";
#else
  Values["tcmalloc"] = "false";
#endif

#ifdef TRI_HAVE_POLL_H
  Values["fd-client-event-handler"] = "poll";
#else
  Values["fd-client-event-handler"] = "select";
#endif

  for (auto& it : Values) {
    arangodb::basics::StringUtils::trimInPlace(it.second);
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get numeric server version
////////////////////////////////////////////////////////////////////////////////

int32_t Version::getNumericServerVersion() {
  char const* apiVersion = ARANGODB_VERSION;
  char const* p = apiVersion;

  // read major version
  while (*p >= '0' && *p <= '9') {
    ++p;
  }

  TRI_ASSERT(*p == '.');
  int32_t major = TRI_Int32String2(apiVersion, (p - apiVersion));

  apiVersion = ++p;

  // read minor version
  while (*p >= '0' && *p <= '9') {
    ++p;
  }

  TRI_ASSERT((*p == '.' || *p == '-' || *p == '\0') && p != apiVersion);
  int32_t minor = TRI_Int32String2(apiVersion, (p - apiVersion));

  return (int32_t)(minor * 100L + major * 10000L);
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get server version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getServerVersion() { return std::string(ARANGODB_VERSION); }

////////////////////////////////////////////////////////////////////////////////
/// @brief get BOOST version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getBoostVersion() {
#ifdef ARANGODB_BOOST_VERSION
  return std::string(ARANGODB_BOOST_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get V8 version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getV8Version() {
#ifdef ARANGODB_V8_VERSION
  return std::string(ARANGODB_V8_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get OpenSSL version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getOpenSSLVersion() {
#ifdef OPENSSL_VERSION_TEXT
  return std::string(OPENSSL_VERSION_TEXT);
#elif defined(ARANGODB_OPENSSL_VERSION)
  return std::string(ARANGODB_OPENSSL_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get libev version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getLibevVersion() {
#ifdef ARANGODB_LIBEV_VERSION
  return std::string(ARANGODB_LIBEV_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get vpack version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getVPackVersion() {
  return arangodb::velocypack::Version::BuildVersion.toString();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get zlib version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getZLibVersion() {
#ifdef ARANGODB_ZLIB_VERSION
  return std::string(ARANGODB_ZLIB_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get ICU version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getICUVersion() {
  UVersionInfo icuVersion;
  char icuVersionString[U_MAX_VERSION_STRING_LENGTH];
  u_getVersion(icuVersion);
  u_versionToString(icuVersion, icuVersionString);

  return icuVersionString;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get repository version
////////////////////////////////////////////////////////////////////////////////

std::string Version::getRepositoryVersion() {
#ifdef TRI_REPOSITORY_VERSION
  return std::string(TRI_REPOSITORY_VERSION);
#else
  return std::string("");
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get build date
////////////////////////////////////////////////////////////////////////////////

std::string Version::getBuildDate() {
// the OpenSuSE build system does not like it, if __DATE__ is used
#ifdef ARANGODB_BUILD_DATE
  return std::string(ARANGODB_BUILD_DATE);
#else
  return std::string(__DATE__).append(" ").append(__TIME__);
#endif
}

////////////////////////////////////////////////////////////////////////////////
/// @brief return a server version string
////////////////////////////////////////////////////////////////////////////////

std::string Version::getVerboseVersionString() {
  std::ostringstream version;

  version << "ArangoDB " << ARANGODB_VERSION_FULL << " "
          << (sizeof(void*) == 4 ? "32" : "64") << "bit"
#ifdef ARANGODB_ENABLE_MAINTAINER_MODE
          << " maintainer mode"
#endif
          << ", using "
#ifdef TRI_HAVE_TCMALLOC
          << "tcmalloc, "
#endif
          << "VPack " << getVPackVersion() << ", "
          << "ICU " << getICUVersion() << ", "
          << "V8 " << getV8Version() << ", " << getOpenSSLVersion();

  return version.str();
}

////////////////////////////////////////////////////////////////////////////////
/// @brief get detailed version information as a (multi-line) string
////////////////////////////////////////////////////////////////////////////////

std::string Version::getDetailed() {
  std::string result;

  for (auto& it : Values) {
    std::string const& value = it.second;

    if (!value.empty()) {
      result.append(it.first);
      result.append(": ");
      result.append(it.second);
#ifdef _WIN32
      result += "\r\n";
#else
      result += "\n";
#endif
    }
  }

  return result;
}

////////////////////////////////////////////////////////////////////////////////
/// @brief JSONize all data
////////////////////////////////////////////////////////////////////////////////

void Version::getJson(TRI_memory_zone_t* zone, TRI_json_t* dst) {
  for (auto const& it : Values) {
    std::string const& value = it.second;

    if (!value.empty()) {
      std::string const& key = it.first;

      TRI_Insert3ObjectJson(
          zone, dst, key.c_str(),
          TRI_CreateStringCopyJson(zone, value.c_str(), value.size()));
    }
  }
}

////////////////////////////////////////////////////////////////////////////////
/// @brief VelocyPack all data
////////////////////////////////////////////////////////////////////////////////

void Version::getVPack(VPackBuilder& dst) {
  for (auto const& it : Values) {
    std::string const& value = it.second;

    if (!value.empty()) {
      dst.add(it.first, VPackValue(value));
    }
  }
}

std::map<std::string, std::string> Version::Values;

{'fraction_non_alphanumeric': 0.3949459955166089, 'fraction_numerical': 0.008457305889545547, 'mean_word_length': 1.3931967812728603, 'pattern_counts': {'":': 2, '<': 93, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1507922', 'n_tokens_mistral': 5171, 'n_tokens_neox': 4909, 'n_words': 1091}