/*
  Copyright (c) DataStax, Inc.

  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.
*/

#include "utils.hpp"

#include "constants.hpp"

#include <algorithm>
#include <assert.h>
#include <functional>
#include <uv.h>

#if (defined(WIN32) || defined(_WIN32))
#include <windows.h>
#else
#include <sched.h>
#include <unistd.h>
#endif

namespace datastax { namespace internal {

String opcode_to_string(int opcode) {
  switch (opcode) {
    case CQL_OPCODE_ERROR:
      return "CQL_OPCODE_ERROR";
    case CQL_OPCODE_STARTUP:
      return "CQL_OPCODE_STARTUP";
    case CQL_OPCODE_READY:
      return "CQL_OPCODE_READY";
    case CQL_OPCODE_AUTHENTICATE:
      return "CQL_OPCODE_AUTHENTICATE";
    case CQL_OPCODE_CREDENTIALS:
      return "CQL_OPCODE_CREDENTIALS";
    case CQL_OPCODE_OPTIONS:
      return "CQL_OPCODE_OPTIONS";
    case CQL_OPCODE_SUPPORTED:
      return "CQL_OPCODE_SUPPORTED";
    case CQL_OPCODE_QUERY:
      return "CQL_OPCODE_QUERY";
    case CQL_OPCODE_RESULT:
      return "CQL_OPCODE_RESULT";
    case CQL_OPCODE_PREPARE:
      return "CQL_OPCODE_PREPARE";
    case CQL_OPCODE_EXECUTE:
      return "CQL_OPCODE_EXECUTE";
    case CQL_OPCODE_REGISTER:
      return "CQL_OPCODE_REGISTER";
    case CQL_OPCODE_EVENT:
      return "CQL_OPCODE_EVENT";
    case CQL_OPCODE_BATCH:
      return "CQL_OPCODE_BATCH";
    case CQL_OPCODE_AUTH_CHALLENGE:
      return "CQL_OPCODE_AUTH_CHALLENGE";
    case CQL_OPCODE_AUTH_RESPONSE:
      return "CQL_OPCODE_AUTH_RESPONSE";
    case CQL_OPCODE_AUTH_SUCCESS:
      return "CQL_OPCODE_AUTH_SUCCESS";
  };
  assert(false);
  return "";
}

String to_string(const CassUuid& uuid) {
  char str[CASS_UUID_STRING_LENGTH];
  cass_uuid_string(uuid, str);
  return String(str);
}

void explode(const String& str, Vector<String>& vec, const char delimiter /* = ',' */) {
  IStringStream stream(str);
  while (!stream.eof()) {
    String token;
    std::getline(stream, token, delimiter);
    if (!trim(token).empty()) {
      vec.push_back(token);
    }
  }
}

String implode(const Vector<String>& vec, const char delimiter /* = ' ' */) {
  String str;
  for (Vector<String>::const_iterator it = vec.begin(), end = vec.end(); it != end; ++it) {
    if (!str.empty()) {
      str.push_back(delimiter);
    }
    str.append(*it);
  }
  return str;
}

bool not_isspace(int c) { return !::isspace(c); }

String& trim(String& str) {
  // Trim front
  str.erase(str.begin(), std::find_if(str.begin(), str.end(), not_isspace));
  // Trim back
  str.erase(std::find_if(str.rbegin(), str.rend(), not_isspace).base(), str.end());
  return str;
}

static bool is_lowercase(const String& str) {
  if (str.empty()) return true;

  char c = str[0];
  if (!(c >= 'a' && c <= 'z')) return false;

  for (String::const_iterator it = str.begin() + 1, end = str.end(); it != end; ++it) {
    char c = *it;
    if (!((c >= '0' && c <= '9') || (c == '_') || (c >= 'a' && c <= 'z'))) {
      return false;
    }
  }
  return true;
}

static String& quote_id(String& str) {
  String temp(str);
  str.clear();
  str.push_back('"');
  for (String::const_iterator i = temp.begin(), end = temp.end(); i != end; ++i) {
    if (*i == '"') {
      str.push_back('"');
      str.push_back('"');
    } else {
      str.push_back(*i);
    }
  }
  str.push_back('"');

  return str;
}

String& escape_id(String& str) { return is_lowercase(str) ? str : quote_id(str); }

int32_t get_pid() {
#if (defined(WIN32) || defined(_WIN32))
  return static_cast<int32_t>(GetCurrentProcessId());
#else
  return static_cast<int32_t>(getpid());
#endif
}

void thread_yield() {
#if defined(WIN32) || defined(_WIN32)
  SwitchToThread();
#else
  sched_yield();
#endif
}

// Code was taken from MSDN documentation see:
// https://docs.microsoft.com/en-us/visualstudio/debugger/how-to-set-a-thread-name-in-native-code
#if defined(_MSC_VER) && defined(_DEBUG)
const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push, 8)
typedef struct tagTHREADNAME_INFO {
  DWORD dwType;     // Must be 0x1000.
  LPCSTR szName;    // Pointer to name (in user addr space).
  DWORD dwThreadID; // Thread ID (-1=caller thread).
  DWORD dwFlags;    // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
#endif
void set_thread_name(const String& thread_name) {
#if defined(_MSC_VER) && defined(_DEBUG)
  THREADNAME_INFO info;
  info.dwType = 0x1000;
  info.szName = thread_name.c_str();
  info.dwThreadID = -1;
  info.dwFlags = 0;
#pragma warning(push)
#pragma warning(disable : 6320 6322)
  __try {
    RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR),
                   reinterpret_cast<ULONG_PTR*>(&info));
  } __except (EXCEPTION_EXECUTE_HANDLER) {
  }
#pragma warning(pop)
#endif
}

}} // namespace datastax::internal
