/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.
 */

#include "Utils.hpp"

#include <chrono>
#include <cstdio>
#include <cstdlib>
#include <iomanip>

#include <ace/INET_Addr.h>
#include <ace/OS.h>
#include <boost/asio.hpp>
#include <boost/dll/import.hpp>
#include <boost/dll/runtime_symbol_info.hpp>
#include <boost/process/detail/config.hpp>

#include "config.h"

namespace apache {
namespace geode {
namespace client {

std::string Utils::getEnv(const char* varName) {
  std::string env;
  if (const auto varValue = std::getenv(varName)) {
    env = varValue;
  }
  return env;
}

std::error_code Utils::getLastError() {
  if (errno != 0) {
    return std::error_code(errno, std::system_category());
  }

  return boost::process::detail::get_last_error();
}

void Utils::parseEndpointString(const char* endpoints, std::string& host,
                                uint16_t& port) {
  std::string endpointsStr(endpoints);
  LOGFINE("Parsing endpoint string [%s]", endpointsStr.c_str());
  // Parse this string to get all hostnames and port numbers.
  std::string endpoint;
  std::string::size_type length = endpointsStr.size();
  std::string::size_type pos = 0;
  pos = endpointsStr.find(':', 0);
  if (pos != std::string::npos) {
    endpoint = endpointsStr.substr(0, pos);
    pos += 1;  // skip ':'
    length -= (pos);
    endpointsStr = endpointsStr.substr(pos, length);
  } else {
    host = "";
    port = 0;
    return;
  }
  // trim white spaces.
  std::string::size_type wpos = endpoint.find_last_not_of(' ');
  if (wpos != std::string::npos) {
    endpoint.erase(wpos + 1);
    wpos = endpoint.find_first_not_of(' ');
    if (wpos != std::string::npos) endpoint.erase(0, wpos);
  }
  host = endpoint;
  port = atoi(endpointsStr.c_str());
}

std::string Utils::convertHostToCanonicalForm(const char* endpoints) {
  if (endpoints == nullptr) return nullptr;
  std::string hostString("");
  uint16_t port = 0;
  std::string endpointsStr(endpoints);
  std::string endpointsStr1(endpoints);
  // Parse this string to get all hostnames and port numbers.
  std::string endpoint;
  std::string::size_type length = endpointsStr.size();
  std::string::size_type pos = 0;
  ACE_TCHAR hostName[256];
  pos = endpointsStr.find(':', 0);
  if (pos != std::string::npos) {
    endpoint = endpointsStr.substr(0, pos);
    pos += 1;  // skip ':'
    length -= (pos);
    endpointsStr = endpointsStr.substr(pos, length);
  } else {
    hostString = "";
    return "";
  }
  hostString = endpoint;
  port = std::stoi(endpointsStr);
  if (hostString == "localhost") {
    auto hostname = boost::asio::ip::host_name();
    if (auto host = ::gethostbyname(hostname.c_str())) {
      return std::string{host->h_name} + ':' + std::to_string(port);
    }
  } else {
    pos = endpointsStr1.find('.', 0);
    if (pos != std::string::npos) {
      ACE_INET_Addr addr(endpoints);
      addr.get_host_name(hostName, 256);
      return std::string(hostName) + ":" + std::to_string(port);
    }
  }
  return endpoints;
}

void Utils::parseEndpointNamesString(
    std::string endpoints, std::unordered_set<std::string>& endpointNames) {
  // Parse this string to get all hostnames and port numbers.
  std::string endpoint;
  std::string::size_type length = endpoints.size();
  std::string::size_type pos = 0;
  do {
    pos = endpoints.find(',', 0);
    if (pos != std::string::npos) {
      endpoint = endpoints.substr(0, pos);
      pos += 1;  // skip ','
      length -= (pos);
      endpoints = endpoints.substr(pos, length);
    } else {
      endpoint = endpoints;
    }
    // trim white spaces.
    std::string::size_type wpos = endpoint.find_last_not_of(' ');
    if (wpos != std::string::npos) {
      endpoint.erase(wpos + 1);
      wpos = endpoint.find_first_not_of(' ');
      if (wpos != std::string::npos) endpoint.erase(0, wpos);
      endpointNames.insert(endpoint);
    }
  } while (pos != std::string::npos);
}

char* Utils::copyString(const char* str) {
  char* resStr = nullptr;
  if (str != nullptr) {
    size_t strSize = strlen(str) + 1;
    resStr = new char[strSize];
    memcpy(resStr, str, strSize);
  }
  return resStr;
}

/**
 * Finds, loads and keeps a copy of requested shared library. Future
 * improvements should use the boost::dll::import to maintain references to
 * shared libraries rather than a synchronized global structure.
 *
 * Uses similar options ans search patterns to the original ACE_DLL
 * implementation.
 *
 * @param libraryName to find or load
 * @return found or loaded shared library
 * @throws IllegalArgumentException if library is not found or otherwise
 * unloadable.
 */
const boost::dll::shared_library& getSharedLibrary(
    const std::string& libraryName) {
  static std::mutex sharedLibrariesMutex;
  static std::unordered_map<std::string,
                            std::shared_ptr<boost::dll::shared_library>>
      sharedLibraries;

  std::lock_guard<decltype(sharedLibrariesMutex)> lock(sharedLibrariesMutex);

  const auto& find = sharedLibraries.find(libraryName);
  if (find == sharedLibraries.end()) {
    auto path = libraryName.empty() ? boost::dll::program_location()
                                    : boost::dll::fs::path{libraryName};
    try {
      return *sharedLibraries
                  .emplace(
                      libraryName,
                      std::make_shared<boost::dll::shared_library>(
                          path,
                          boost::dll::load_mode::rtld_global |
                              boost::dll::load_mode::rtld_lazy |
                              boost::dll::load_mode::append_decorations |
                              boost::dll::load_mode::search_system_folders))
                  .first->second;
    } catch (const boost::dll::fs::system_error& e) {
      throw IllegalArgumentException("cannot open library: \"" + path.string() +
                                     "\": reason: " + e.what());
    }
  }

  return *find->second;
}

void* Utils::getFactoryFunctionVoid(const std::string& lib,
                                    const std::string& funcName) {
  try {
    const auto& sharedLibrary = getSharedLibrary(lib);
    return reinterpret_cast<void*>(sharedLibrary.get<void*()>(funcName));
  } catch (const boost::dll::fs::system_error&) {
    std::string location =
        lib.empty() ? "the application" : "library \"" + lib + "\"";
    throw IllegalArgumentException("cannot find factory function " + funcName +
                                   " in " + location);
  }
}

std::string Utils::convertBytesToString(const uint8_t* bytes, size_t length,
                                        size_t maxLength) {
  if (bytes != nullptr) {
    length = std::min(length, maxLength);
    std::stringstream ss;
    ss << std::setfill('0') << std::hex;
    for (size_t i = 0; i < length; ++i) {
      ss << std::setw(2) << static_cast<int>(bytes[i]);
    }
    return ss.str();
  }
  return "";
}

std::string Utils::convertBytesToString(const int8_t* bytes, size_t length,
                                        size_t maxLength) {
  return Utils::convertBytesToString(reinterpret_cast<const uint8_t*>(bytes),
                                     length, maxLength);
}

int64_t Utils::startStatOpTime() {
  return std::chrono::duration_cast<std::chrono::nanoseconds>(
             std::chrono::steady_clock::now().time_since_epoch())
      .count();
}

void Utils::updateStatOpTime(statistics::Statistics* m_regionStats,
                             int32_t statId, int64_t start) {
  m_regionStats->incLong(statId, startStatOpTime() - start);
}

std::string Utils::getSystemInfo() {
  std::string sysname{"Unknown"};
  std::string machine{"Unknown"};
  std::string nodename{"Unknown"};
  std::string release{"Unknown"};
  std::string version{"Unknown"};

#if defined(HAVE_uname)
  struct utsname name;
  auto rc = ::uname(&name);
  if (rc == 0) {
    sysname = name.sysname;
    machine = name.machine;
    nodename = name.nodename;
    release = name.release;
    version = name.version;
  }
#elif defined(_WIN32) /* HAVE_uname */
  sysname = "Win32";

/* Since MS found it necessary to deprecate these. */
#pragma warning(push)
#pragma warning(disable : 4996)
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
#endif /* __clang__ */
  OSVERSIONINFOA vinfo;
  vinfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOA);
  ::GetVersionExA(&vinfo);
#if defined(__clang__)
#pragma clang diagnostic pop
#endif /* __clang__ */
#pragma warning(pop)

  if (vinfo.dwPlatformId == VER_PLATFORM_WIN32_NT) {
    // Get information from the two structures
    release = "Windows NT " + std::to_string(vinfo.dwMajorVersion) + '.' +
              std::to_string(vinfo.dwMinorVersion);
    version = "Build " + std::to_string(vinfo.dwBuildNumber) + ' ' +
              vinfo.szCSDVersion;
  }

  {
    HKEY key;
    DWORD size = 0;
    DWORD type = 0;
    auto key_name = "ProcessorNameString";
    auto key_path = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0";
    auto rc = ::RegOpenKeyExA(HKEY_LOCAL_MACHINE, key_path, 0, KEY_READ, &key);
    if (rc == ERROR_SUCCESS) {
      rc = ::RegQueryValueExA(key, key_name, nullptr, &type, nullptr, &size);
      if (rc == ERROR_SUCCESS && type == REG_SZ && size > 0) {
        std::vector<char> buffer(size, 0);
        auto ptr = reinterpret_cast<LPBYTE>(buffer.data());
        rc = ::RegQueryValueExA(key, key_name, nullptr, &type, ptr, &size);
        if (rc == ERROR_SUCCESS && buffer[0] != '\0') {
          machine = buffer.data();
        }
      }

      ::RegCloseKey(key);
    }
  }

  nodename = boost::asio::ip::host_name();
#endif /* _WIN32 */

  std::string info = "SystemName=";
  info += sysname;
  info += " Machine=";
  info += machine;
  info += " Host=";
  info += nodename;
  info += " Release=";
  info += release;
  info += " Version=";
  info += version;

  return info;
}

}  // namespace client
}  // namespace geode
}  // namespace apache
