// Copyright 2024 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef SRC_DEVELOPER_FUCHSIA_CONTROLLER_CPP_FIDL_CODEC_UTILS_H_
#define SRC_DEVELOPER_FUCHSIA_CONTROLLER_CPP_FIDL_CODEC_UTILS_H_

#include <Python.h>

#include <locale>
#include <sstream>
#include <string>
#include <unordered_set>

namespace fuchsia_controller::fidl_codec::utils {

// Converts camel case to lower snake case. Does not handle acronyms.
inline std::string ToLowerSnake(std::string_view s) {
  std::stringstream ss;
  auto iter = s.cbegin();
  ss.put(std::tolower(*iter, std::locale()));
  iter++;
  for (; iter != s.cend(); ++iter) {
    auto c = *iter;
    if (std::isupper(c)) {
      ss.put('_');
    }
    ss.put(std::tolower(c, std::locale()));
  }
  return ss.str();
}

// This is a recreation of the "normalize_member_name" function from Python.
inline std::string NormalizeMemberName(std::string_view s) {
  // These keywords are taken from the Python docs:
  // https://docs.python.org/3/reference/lexical_analysis.html#keywords
  // Uppercase keywords have been omitted.
  static std::unordered_set<std::string> python_keywords = {
      // clang-format off
      // LINT.IfChange
      // keep-sorted start
      "ArithmeticError",
      "AssertionError",
      "AttributeError",
      "BaseException",
      "BaseExceptionGroup",
      "BlockingIOError",
      "BrokenPipeError",
      "BufferError",
      "BytesWarning",
      "ChildProcessError",
      "ConnectionAbortedError",
      "ConnectionError",
      "ConnectionRefusedError",
      "ConnectionResetError",
      "DeprecationWarning",
      "EOFError",
      "Ellipsis",
      "EncodingWarning",
      "EnvironmentError",
      "Exception",
      "ExceptionGroup",
      "False",
      "FileExistsError",
      "FileNotFoundError",
      "FloatingPointError",
      "FutureWarning",
      "GeneratorExit",
      "IOError",
      "ImportError",
      "ImportWarning",
      "IndentationError",
      "IndexError",
      "InterruptedError",
      "IsADirectoryError",
      "KeyError",
      "KeyboardInterrupt",
      "LookupError",
      "MemoryError",
      "ModuleNotFoundError",
      "NameError",
      "None",
      "NotADirectoryError",
      "NotImplemented",
      "NotImplementedError",
      "OSError",
      "OverflowError",
      "PendingDeprecationWarning",
      "PermissionError",
      "ProcessLookupError",
      "RecursionError",
      "ReferenceError",
      "ResourceWarning",
      "RuntimeError",
      "RuntimeWarning",
      "StopAsyncIteration",
      "StopIteration",
      "SyntaxError",
      "SyntaxWarning",
      "SystemError",
      "SystemExit",
      "TabError",
      "TimeoutError",
      "True",
      "TypeError",
      "UnboundLocalError",
      "UnicodeDecodeError",
      "UnicodeEncodeError",
      "UnicodeError",
      "UnicodeTranslateError",
      "UnicodeWarning",
      "UserWarning",
      "ValueError",
      "Warning",
      "ZeroDivisionError",
      "abs",
      "aiter",
      "all",
      "and",
      "anext",
      "any",
      "as",
      "ascii",
      "assert",
      "async",
      "await",
      "bin",
      "bool",
      "break",
      "breakpoint",
      "bytearray",
      "bytes",
      "callable",
      "case",
      "chr",
      "class",
      "classmethod",
      "compile",
      "complex",
      "continue",
      "copyright",
      "credits",
      "def",
      "del",
      "delattr",
      "dict",
      "dir",
      "divmod",
      "elif",
      "else",
      "enumerate",
      "eval",
      "except",
      "exec",
      "exit",
      "filter",
      "finally",
      "float",
      "for",
      "format",
      "from",
      "frozenset",
      "getattr",
      "global",
      "globals",
      "hasattr",
      "hash",
      "help",
      "hex",
      "id",
      "if",
      "import",
      "in",
      "input",
      "int",
      "is",
      "isinstance",
      "issubclass",
      "iter",
      "lambda",
      "len",
      "license",
      "list",
      "locals",
      "map",
      "match",
      "max",
      "memoryview",
      "min",
      "next",
      "nonlocal",
      "not",
      "object",
      "oct",
      "open",
      "or",
      "ord",
      "pass",
      "pow",
      "print",
      "property",
      "quit",
      "raise",
      "range",
      "repr",
      "return",
      "reversed",
      "round",
      "self",
      "set",
      "setattr",
      "slice",
      "sorted",
      "staticmethod",
      "str",
      "sum",
      "super",
      "try",
      "tuple",
      "type",
      "vars",
      "while",
      "with",
      "yield",
      "zip",
      // keep-sorted end
      // LINT.ThenChange(//src/developer/fuchsia-controller/cpp/fidl_codec/utils.h, //tools/fidl/fidlgen_python/codegen/ir.go, //tools/fidl/gidl/backend/python/conformance.go)
      // clang-format on
  };
  auto lower_snake = ToLowerSnake(s);
  if (python_keywords.contains(lower_snake)) {
    lower_snake.append("_");
  }
  return lower_snake;
}

static constexpr uint32_t MINUS_ONE_U32 = std::numeric_limits<uint32_t>::max();
static constexpr uint64_t MINUS_ONE_U64 = std::numeric_limits<uint64_t>::max();
static_assert(sizeof(unsigned long long) == sizeof(uint64_t));  // NOLINT

inline uint32_t PyLong_AsU32(PyObject* py_long) {
  auto res = PyLong_AsUnsignedLongLong(py_long);
  if (res > static_cast<uint64_t>(MINUS_ONE_U32)) {
    PyErr_Format(PyExc_OverflowError, "Value %" PRIu64 " too large for u32", res);
    return MINUS_ONE_U32;
  }
  return static_cast<uint32_t>(res);
}

inline uint64_t PyLong_AsU64(PyObject* py_long) {
  return static_cast<uint64_t>(PyLong_AsUnsignedLongLong(py_long));
}

class Buffer {
 public:
  explicit Buffer(Py_buffer buf) : buffer_(buf) {}
  ~Buffer() { PyBuffer_Release(&buffer_); }
  Py_ssize_t len() const { return buffer_.len; }
  void* buf() const { return buffer_.buf; }

  Buffer(const Buffer&) = delete;
  Buffer& operator=(const Buffer&) = delete;
  Buffer(Buffer&&) = delete;
  Buffer& operator=(Buffer&&) = delete;

 private:
  Py_buffer buffer_;
};

}  // namespace fuchsia_controller::fidl_codec::utils

#endif  // SRC_DEVELOPER_FUCHSIA_CONTROLLER_CPP_FIDL_CODEC_UTILS_H_
