/*
  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 "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 = (DWORD)-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
