/*
 * Copyright 2016 Google Inc. All rights reserved.
 *
 * 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.
 */

// clang-format off
// Dont't remove `format off`, it prevent reordering of win-includes.

#if defined(__MINGW32__) || defined(__MINGW64__) || defined(__CYGWIN__) || \
    defined(__QNXNTO__)
#  define _POSIX_C_SOURCE 200809L
#  define _XOPEN_SOURCE 700L
#endif

#ifdef _WIN32
#  ifndef WIN32_LEAN_AND_MEAN
#    define WIN32_LEAN_AND_MEAN
#  endif
#  ifndef NOMINMAX
#    define NOMINMAX
#  endif
#  ifdef _MSC_VER
#    include <crtdbg.h>
#  endif
#  include <windows.h>  // Must be included before <direct.h>
#  include <direct.h>
#  include <winbase.h>
#  undef interface  // This is also important because of reasons
#endif
// clang-format on

#include "flatbuffers/util.h"

#include <sys/stat.h>

#include <clocale>
#include <cstdlib>
#include <functional>
#include <fstream>

#include "flatbuffers/base.h"

namespace flatbuffers {

bool FileExistsRaw(const char *name) {
  std::ifstream ifs(name);
  return ifs.good();
}

bool LoadFileRaw(const char *name, bool binary, std::string *buf) {
  if (DirExists(name)) return false;
  std::ifstream ifs(name, binary ? std::ifstream::binary : std::ifstream::in);
  if (!ifs.is_open()) return false;
  if (binary) {
    // The fastest way to read a file into a string.
    ifs.seekg(0, std::ios::end);
    auto size = ifs.tellg();
    (*buf).resize(static_cast<size_t>(size));
    ifs.seekg(0, std::ios::beg);
    ifs.read(&(*buf)[0], (*buf).size());
  } else {
    // This is slower, but works correctly on all platforms for text files.
    std::ostringstream oss;
    oss << ifs.rdbuf();
    *buf = oss.str();
  }
  return !ifs.bad();
}

static LoadFileFunction g_load_file_function = LoadFileRaw;
static FileExistsFunction g_file_exists_function = FileExistsRaw;

bool LoadFile(const char *name, bool binary, std::string *buf) {
  FLATBUFFERS_ASSERT(g_load_file_function);
  return g_load_file_function(name, binary, buf);
}

bool FileExists(const char *name) {
  FLATBUFFERS_ASSERT(g_file_exists_function);
  return g_file_exists_function(name);
}

bool DirExists(const char *name) {
  // clang-format off

  #ifdef _WIN32
    #define flatbuffers_stat _stat
    #define FLATBUFFERS_S_IFDIR _S_IFDIR
  #else
    #define flatbuffers_stat stat
    #define FLATBUFFERS_S_IFDIR S_IFDIR
  #endif
  // clang-format on
  struct flatbuffers_stat file_info;
  if (flatbuffers_stat(name, &file_info) != 0) return false;
  return (file_info.st_mode & FLATBUFFERS_S_IFDIR) != 0;
}

LoadFileFunction SetLoadFileFunction(LoadFileFunction load_file_function) {
  LoadFileFunction previous_function = g_load_file_function;
  g_load_file_function = load_file_function ? load_file_function : LoadFileRaw;
  return previous_function;
}

FileExistsFunction SetFileExistsFunction(
    FileExistsFunction file_exists_function) {
  FileExistsFunction previous_function = g_file_exists_function;
  g_file_exists_function =
      file_exists_function ? file_exists_function : FileExistsRaw;
  return previous_function;
}

bool SaveFile(const char *name, const char *buf, size_t len, bool binary) {
  std::ofstream ofs(name, binary ? std::ofstream::binary : std::ofstream::out);
  if (!ofs.is_open()) return false;
  ofs.write(buf, len);
  return !ofs.bad();
}

// We internally store paths in posix format ('/'). Paths supplied
// by the user should go through PosixPath to ensure correct behavior
// on Windows when paths are string-compared.

static const char kPathSeparatorWindows = '\\';
static const char *PathSeparatorSet = "\\/";  // Intentionally no ':'

std::string StripExtension(const std::string &filepath) {
  size_t i = filepath.find_last_of('.');
  return i != std::string::npos ? filepath.substr(0, i) : filepath;
}

std::string GetExtension(const std::string &filepath) {
  size_t i = filepath.find_last_of('.');
  return i != std::string::npos ? filepath.substr(i + 1) : "";
}

std::string StripPath(const std::string &filepath) {
  size_t i = filepath.find_last_of(PathSeparatorSet);
  return i != std::string::npos ? filepath.substr(i + 1) : filepath;
}

std::string StripFileName(const std::string &filepath) {
  size_t i = filepath.find_last_of(PathSeparatorSet);
  return i != std::string::npos ? filepath.substr(0, i) : "";
}

std::string ConCatPathFileName(const std::string &path,
                               const std::string &filename) {
  std::string filepath = path;
  if (filepath.length()) {
    char &filepath_last_character = filepath.back();
    if (filepath_last_character == kPathSeparatorWindows) {
      filepath_last_character = kPathSeparator;
    } else if (filepath_last_character != kPathSeparator) {
      filepath += kPathSeparator;
    }
  }
  filepath += filename;
  // Ignore './' at the start of filepath.
  if (filepath[0] == '.' && filepath[1] == kPathSeparator) {
    filepath.erase(0, 2);
  }
  return filepath;
}

std::string PosixPath(const char *path) {
  std::string p = path;
  std::replace(p.begin(), p.end(), '\\', '/');
  return p;
}
std::string PosixPath(const std::string &path) {
  return PosixPath(path.c_str());
}

void EnsureDirExists(const std::string &filepath) {
  auto parent = StripFileName(filepath);
  if (parent.length()) EnsureDirExists(parent);
    // clang-format off

  #ifdef _WIN32
    (void)_mkdir(filepath.c_str());
  #else
    mkdir(filepath.c_str(), S_IRWXU|S_IRGRP|S_IXGRP);
  #endif
  // clang-format on
}

std::string AbsolutePath(const std::string &filepath) {
  // clang-format off

  #ifdef FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION
    return filepath;
  #else
    #ifdef _WIN32
      char abs_path[MAX_PATH];
      return GetFullPathNameA(filepath.c_str(), MAX_PATH, abs_path, nullptr)
    #else
      char *abs_path_temp = realpath(filepath.c_str(), nullptr);
      bool success = abs_path_temp != nullptr;
      std::string abs_path;
      if(success) {
        abs_path = abs_path_temp;
        free(abs_path_temp);
      }
      return success
    #endif
      ? abs_path
      : filepath;
  #endif // FLATBUFFERS_NO_ABSOLUTE_PATH_RESOLUTION
  // clang-format on
}

std::string RelativeToRootPath(const std::string &project,
                               const std::string &filepath) {
  std::string absolute_project = PosixPath(AbsolutePath(project));
  if (absolute_project.back() != '/') absolute_project += "/";
  std::string absolute_filepath = PosixPath(AbsolutePath(filepath));

  // Find the first character where they disagree.
  // The previous directory is the lowest common ancestor;
  const char *a = absolute_project.c_str();
  const char *b = absolute_filepath.c_str();
  size_t common_prefix_len = 0;
  while (*a != '\0' && *b != '\0' && *a == *b) {
    if (*a == '/') common_prefix_len = a - absolute_project.c_str();
    a++;
    b++;
  }
  // the number of ../ to prepend to b depends on the number of remaining
  // directories in A.
  const char *suffix = absolute_project.c_str() + common_prefix_len;
  size_t num_up = 0;
  while (*suffix != '\0')
    if (*suffix++ == '/') num_up++;
  num_up--;  // last one is known to be '/'.
  std::string result = "//";
  for (size_t i = 0; i < num_up; i++) result += "../";
  result += absolute_filepath.substr(common_prefix_len + 1);

  return result;
}

// Locale-independent code.
#if defined(FLATBUFFERS_LOCALE_INDEPENDENT) && \
    (FLATBUFFERS_LOCALE_INDEPENDENT > 0)

// clang-format off
// Allocate locale instance at startup of application.
ClassicLocale ClassicLocale::instance_;

#ifdef _MSC_VER
  ClassicLocale::ClassicLocale()
    : locale_(_create_locale(LC_ALL, "C")) {}
  ClassicLocale::~ClassicLocale() { _free_locale(locale_); }
#else
  ClassicLocale::ClassicLocale()
    : locale_(newlocale(LC_ALL, "C", nullptr)) {}
  ClassicLocale::~ClassicLocale() { freelocale(locale_); }
#endif
// clang-format on

#endif  // !FLATBUFFERS_LOCALE_INDEPENDENT

std::string RemoveStringQuotes(const std::string &s) {
  auto ch = *s.c_str();
  return ((s.size() >= 2) && (ch == '\"' || ch == '\'') && (ch == s.back()))
             ? s.substr(1, s.length() - 2)
             : s;
}

bool SetGlobalTestLocale(const char *locale_name, std::string *_value) {
  const auto the_locale = setlocale(LC_ALL, locale_name);
  if (!the_locale) return false;
  if (_value) *_value = std::string(the_locale);
  return true;
}

bool ReadEnvironmentVariable(const char *var_name, std::string *_value) {
#ifdef _MSC_VER
  __pragma(warning(disable : 4996));  // _CRT_SECURE_NO_WARNINGS
#endif
  auto env_str = std::getenv(var_name);
  if (!env_str) return false;
  if (_value) *_value = std::string(env_str);
  return true;
}

void SetupDefaultCRTReportMode() {
  // clang-format off

  #ifdef _MSC_VER
    // By default, send all reports to STDOUT to prevent CI hangs.
    // Enable assert report box [Abort|Retry|Ignore] if a debugger is present.
    const int dbg_mode = (_CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG) |
                         (IsDebuggerPresent() ? _CRTDBG_MODE_WNDW : 0);
    (void)dbg_mode; // release mode fix
    // CrtDebug reports to _CRT_WARN channel.
    _CrtSetReportMode(_CRT_WARN, dbg_mode);
    _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDOUT);
    // The assert from <assert.h> reports to _CRT_ERROR channel
    _CrtSetReportMode(_CRT_ERROR, dbg_mode);
    _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDOUT);
    // Internal CRT assert channel?
    _CrtSetReportMode(_CRT_ASSERT, dbg_mode);
    _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDOUT);
  #endif

  // clang-format on
}

namespace {

static std::string ToCamelCase(const std::string &input, bool first) {
  std::string s;
  for (size_t i = 0; i < input.length(); i++) {
    if (!i && first)
      s += CharToUpper(input[i]);
    else if (input[i] == '_' && i + 1 < input.length())
      s += CharToUpper(input[++i]);
    else
      s += input[i];
  }
  return s;
}

static std::string ToSnakeCase(const std::string &input, bool screaming) {
  std::string s;
  for (size_t i = 0; i < input.length(); i++) {
    if (i == 0) {
      s += screaming ? CharToUpper(input[i]) : CharToLower(input[i]);
    } else if (input[i] == '_') {
      s += '_';
    } else if (!islower(input[i])) {
      // Prevent duplicate underscores for Upper_Snake_Case strings
      // and UPPERCASE strings.
      if (islower(input[i - 1])) { s += '_'; }
      s += screaming ? CharToUpper(input[i]) : CharToLower(input[i]);
    } else {
      s += screaming ? CharToUpper(input[i]) : input[i];
    }
  }
  return s;
}

static std::string ToAll(const std::string &input,
                         std::function<char(const char)> transform) {
  std::string s;
  for (size_t i = 0; i < input.length(); i++) { s += transform(input[i]); }
  return s;
}

static std::string CamelToSnake(const std::string &input) {
  std::string s;
  for (size_t i = 0; i < input.length(); i++) {
    if (i == 0) {
      s += CharToLower(input[i]);
    } else if (input[i] == '_') {
      s += '_';
    } else if (!islower(input[i])) {
      // Prevent duplicate underscores for Upper_Snake_Case strings
      // and UPPERCASE strings.
      if (islower(input[i - 1])) { s += '_'; }
      s += CharToLower(input[i]);
    } else {
      s += input[i];
    }
  }
  return s;
}

static std::string DasherToSnake(const std::string &input) {
  std::string s;
  for (size_t i = 0; i < input.length(); i++) {
    if (input[i] == '-') {
      s += "_";
    } else {
      s += input[i];
    }
  }
  return s;
}

static std::string ToDasher(const std::string &input) {
  std::string s;
  char p = 0;
  for (size_t i = 0; i < input.length(); i++) {
    char const &c = input[i];
    if (c == '_') {
      if (i > 0 && p != kPathSeparator &&
          // The following is a special case to ignore digits after a _. This is
          // because ThisExample3 would be converted to this_example_3 in the
          // CamelToSnake conversion, and then dasher would do this-example-3,
          // but it expects this-example3.
          !(i + 1 < input.length() && isdigit(input[i + 1])))
        s += "-";
    } else {
      s += c;
    }
    p = c;
  }
  return s;
}

}  // namespace

// Converts foo_bar_123baz_456 to foo_bar123_baz456
static std::string SnakeToSnake2(const std::string &s) {
  if (s.length() <= 1) return s;
  std::string result;
  result.reserve(s.size());
  for (size_t i = 0; i < s.length() - 1; i++) {
    if (s[i] == '_' && isdigit(s[i + 1])) {
      continue;  // Move the `_` until after the digits.
    }

    result.push_back(s[i]);

    if (isdigit(s[i]) && isalpha(s[i + 1]) && islower(s[i + 1])) {
      result.push_back('_');
    }
  }
  result.push_back(s.back());

  return result;
}

std::string ConvertCase(const std::string &input, Case output_case,
                        Case input_case) {
  if (output_case == Case::kKeep) return input;
  // The output cases expect snake_case inputs, so if we don't have that input
  // format, try to convert to snake_case.
  switch (input_case) {
    case Case::kLowerCamel:
    case Case::kUpperCamel:
      return ConvertCase(CamelToSnake(input), output_case);
    case Case::kDasher: return ConvertCase(DasherToSnake(input), output_case);
    case Case::kKeep: printf("WARNING: Converting from kKeep case.\n"); break;
    default:
    case Case::kSnake:
    case Case::kScreamingSnake:
    case Case::kAllLower:
    case Case::kAllUpper: break;
  }

  switch (output_case) {
    case Case::kUpperCamel: return ToCamelCase(input, true);
    case Case::kLowerCamel: return ToCamelCase(input, false);
    case Case::kSnake: return input;
    case Case::kScreamingSnake: return ToSnakeCase(input, true);
    case Case::kAllUpper: return ToAll(input, CharToUpper);
    case Case::kAllLower: return ToAll(input, CharToLower);
    case Case::kDasher: return ToDasher(input);
    case Case::kSnake2: return SnakeToSnake2(input);
    default:
    case Case::kUnknown: return input;
  }
}

}  // namespace flatbuffers
