///
/// JHybridNetSocketDriverSpec.cpp
/// This file was generated by nitrogen. DO NOT MODIFY THIS FILE.
/// https://github.com/mrousavy/nitro
/// Copyright © Marc Rousavy @ Margelo
///

#include "JHybridNetSocketDriverSpec.hpp"



#include <NitroModules/ArrayBuffer.hpp>
#include <functional>
#include "JFunc_void_double_std__shared_ptr_ArrayBuffer_.hpp"
#include <NitroModules/JNICallable.hpp>
#include <NitroModules/JArrayBuffer.hpp>
#include <string>
#include <optional>

namespace margelo::nitro::net {

  std::shared_ptr<JHybridNetSocketDriverSpec> JHybridNetSocketDriverSpec::JavaPart::getJHybridNetSocketDriverSpec() {
    auto hybridObject = JHybridObject::JavaPart::getJHybridObject();
    auto castHybridObject = std::dynamic_pointer_cast<JHybridNetSocketDriverSpec>(hybridObject);
    if (castHybridObject == nullptr) [[unlikely]] {
      throw std::runtime_error("Failed to downcast JHybridObject to JHybridNetSocketDriverSpec!");
    }
    return castHybridObject;
  }

  jni::local_ref<JHybridNetSocketDriverSpec::CxxPart::jhybriddata> JHybridNetSocketDriverSpec::CxxPart::initHybrid(jni::alias_ref<jhybridobject> jThis) {
    return makeCxxInstance(jThis);
  }

  std::shared_ptr<JHybridObject> JHybridNetSocketDriverSpec::CxxPart::createHybridObject(const jni::local_ref<JHybridObject::JavaPart>& javaPart) {
    auto castJavaPart = jni::dynamic_ref_cast<JHybridNetSocketDriverSpec::JavaPart>(javaPart);
    if (castJavaPart == nullptr) [[unlikely]] {
      throw std::runtime_error("Failed to cast JHybridObject::JavaPart to JHybridNetSocketDriverSpec::JavaPart!");
    }
    return std::make_shared<JHybridNetSocketDriverSpec>(castJavaPart);
  }

  void JHybridNetSocketDriverSpec::CxxPart::registerNatives() {
    registerHybrid({
      makeNativeMethod("initHybrid", JHybridNetSocketDriverSpec::CxxPart::initHybrid),
    });
  }

  // Properties
  double JHybridNetSocketDriverSpec::getId() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<double()>("getId");
    auto __result = method(_javaPart);
    return __result;
  }
  std::function<void(double /* event */, const std::shared_ptr<ArrayBuffer>& /* data */)> JHybridNetSocketDriverSpec::getOnEvent() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JFunc_void_double_std__shared_ptr_ArrayBuffer_::javaobject>()>("getOnEvent_cxx");
    auto __result = method(_javaPart);
    return [&]() -> std::function<void(double /* event */, const std::shared_ptr<ArrayBuffer>& /* data */)> {
      if (__result->isInstanceOf(JFunc_void_double_std__shared_ptr_ArrayBuffer__cxx::javaClassStatic())) [[likely]] {
        auto downcast = jni::static_ref_cast<JFunc_void_double_std__shared_ptr_ArrayBuffer__cxx::javaobject>(__result);
        return downcast->cthis()->getFunction();
      } else {
        auto __resultRef = jni::make_global(__result);
        return JNICallable<JFunc_void_double_std__shared_ptr_ArrayBuffer_, void(double, std::shared_ptr<ArrayBuffer>)>(std::move(__resultRef));
      }
    }();
  }
  void JHybridNetSocketDriverSpec::setOnEvent(const std::function<void(double /* event */, const std::shared_ptr<ArrayBuffer>& /* data */)>& onEvent) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_double_std__shared_ptr_ArrayBuffer_::javaobject> /* onEvent */)>("setOnEvent_cxx");
    method(_javaPart, JFunc_void_double_std__shared_ptr_ArrayBuffer__cxx::fromCpp(onEvent));
  }

  // Methods
  void JHybridNetSocketDriverSpec::connect(const std::string& host, double port) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* host */, double /* port */)>("connect");
    method(_javaPart, jni::make_jstring(host), port);
  }
  void JHybridNetSocketDriverSpec::connectTLS(const std::string& host, double port, const std::optional<std::string>& serverName, std::optional<bool> rejectUnauthorized) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* host */, double /* port */, jni::alias_ref<jni::JString> /* serverName */, jni::alias_ref<jni::JBoolean> /* rejectUnauthorized */)>("connectTLS");
    method(_javaPart, jni::make_jstring(host), port, serverName.has_value() ? jni::make_jstring(serverName.value()) : nullptr, rejectUnauthorized.has_value() ? jni::JBoolean::valueOf(rejectUnauthorized.value()) : nullptr);
  }
  void JHybridNetSocketDriverSpec::connectTLSWithContext(const std::string& host, double port, const std::optional<std::string>& serverName, std::optional<bool> rejectUnauthorized, std::optional<double> secureContextId) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* host */, double /* port */, jni::alias_ref<jni::JString> /* serverName */, jni::alias_ref<jni::JBoolean> /* rejectUnauthorized */, jni::alias_ref<jni::JDouble> /* secureContextId */)>("connectTLSWithContext");
    method(_javaPart, jni::make_jstring(host), port, serverName.has_value() ? jni::make_jstring(serverName.value()) : nullptr, rejectUnauthorized.has_value() ? jni::JBoolean::valueOf(rejectUnauthorized.value()) : nullptr, secureContextId.has_value() ? jni::JDouble::valueOf(secureContextId.value()) : nullptr);
  }
  std::optional<std::string> JHybridNetSocketDriverSpec::getAuthorizationError() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getAuthorizationError");
    auto __result = method(_javaPart);
    return __result != nullptr ? std::make_optional(__result->toStdString()) : std::nullopt;
  }
  std::optional<std::string> JHybridNetSocketDriverSpec::getProtocol() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getProtocol");
    auto __result = method(_javaPart);
    return __result != nullptr ? std::make_optional(__result->toStdString()) : std::nullopt;
  }
  std::optional<std::string> JHybridNetSocketDriverSpec::getCipher() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getCipher");
    auto __result = method(_javaPart);
    return __result != nullptr ? std::make_optional(__result->toStdString()) : std::nullopt;
  }
  std::optional<std::string> JHybridNetSocketDriverSpec::getALPN() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getALPN");
    auto __result = method(_javaPart);
    return __result != nullptr ? std::make_optional(__result->toStdString()) : std::nullopt;
  }
  std::optional<std::string> JHybridNetSocketDriverSpec::getPeerCertificateJSON() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getPeerCertificateJSON");
    auto __result = method(_javaPart);
    return __result != nullptr ? std::make_optional(__result->toStdString()) : std::nullopt;
  }
  std::optional<std::string> JHybridNetSocketDriverSpec::getEphemeralKeyInfo() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getEphemeralKeyInfo");
    auto __result = method(_javaPart);
    return __result != nullptr ? std::make_optional(__result->toStdString()) : std::nullopt;
  }
  std::optional<std::string> JHybridNetSocketDriverSpec::getSharedSigalgs() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getSharedSigalgs");
    auto __result = method(_javaPart);
    return __result != nullptr ? std::make_optional(__result->toStdString()) : std::nullopt;
  }
  bool JHybridNetSocketDriverSpec::isSessionReused() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("isSessionReused");
    auto __result = method(_javaPart);
    return static_cast<bool>(__result);
  }
  std::optional<std::shared_ptr<ArrayBuffer>> JHybridNetSocketDriverSpec::getSession() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JArrayBuffer::javaobject>()>("getSession");
    auto __result = method(_javaPart);
    return __result != nullptr ? std::make_optional(__result->cthis()->getArrayBuffer()) : std::nullopt;
  }
  void JHybridNetSocketDriverSpec::setSession(const std::shared_ptr<ArrayBuffer>& session) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JArrayBuffer::javaobject> /* session */)>("setSession");
    method(_javaPart, JArrayBuffer::wrap(session));
  }
  void JHybridNetSocketDriverSpec::connectUnix(const std::string& path) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* path */)>("connectUnix");
    method(_javaPart, jni::make_jstring(path));
  }
  void JHybridNetSocketDriverSpec::connectUnixTLS(const std::string& path, const std::optional<std::string>& serverName, std::optional<bool> rejectUnauthorized) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* path */, jni::alias_ref<jni::JString> /* serverName */, jni::alias_ref<jni::JBoolean> /* rejectUnauthorized */)>("connectUnixTLS");
    method(_javaPart, jni::make_jstring(path), serverName.has_value() ? jni::make_jstring(serverName.value()) : nullptr, rejectUnauthorized.has_value() ? jni::JBoolean::valueOf(rejectUnauthorized.value()) : nullptr);
  }
  void JHybridNetSocketDriverSpec::connectUnixTLSWithContext(const std::string& path, const std::optional<std::string>& serverName, std::optional<bool> rejectUnauthorized, std::optional<double> secureContextId) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* path */, jni::alias_ref<jni::JString> /* serverName */, jni::alias_ref<jni::JBoolean> /* rejectUnauthorized */, jni::alias_ref<jni::JDouble> /* secureContextId */)>("connectUnixTLSWithContext");
    method(_javaPart, jni::make_jstring(path), serverName.has_value() ? jni::make_jstring(serverName.value()) : nullptr, rejectUnauthorized.has_value() ? jni::JBoolean::valueOf(rejectUnauthorized.value()) : nullptr, secureContextId.has_value() ? jni::JDouble::valueOf(secureContextId.value()) : nullptr);
  }
  void JHybridNetSocketDriverSpec::write(const std::shared_ptr<ArrayBuffer>& data) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JArrayBuffer::javaobject> /* data */)>("write");
    method(_javaPart, JArrayBuffer::wrap(data));
  }
  void JHybridNetSocketDriverSpec::pause() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("pause");
    method(_javaPart);
  }
  void JHybridNetSocketDriverSpec::resume() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("resume");
    method(_javaPart);
  }
  void JHybridNetSocketDriverSpec::shutdown() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("shutdown");
    method(_javaPart);
  }
  void JHybridNetSocketDriverSpec::setTimeout(double timeout) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(double /* timeout */)>("setTimeout");
    method(_javaPart, timeout);
  }
  void JHybridNetSocketDriverSpec::destroy() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("destroy");
    method(_javaPart);
  }
  void JHybridNetSocketDriverSpec::resetAndDestroy() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("resetAndDestroy");
    method(_javaPart);
  }
  void JHybridNetSocketDriverSpec::enableKeylog() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("enableKeylog");
    method(_javaPart);
  }
  void JHybridNetSocketDriverSpec::enableTrace() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("enableTrace");
    method(_javaPart);
  }
  std::optional<std::shared_ptr<ArrayBuffer>> JHybridNetSocketDriverSpec::exportKeyingMaterial(double length, const std::string& label, const std::optional<std::shared_ptr<ArrayBuffer>>& context) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JArrayBuffer::javaobject>(double /* length */, jni::alias_ref<jni::JString> /* label */, jni::alias_ref<JArrayBuffer::javaobject> /* context */)>("exportKeyingMaterial");
    auto __result = method(_javaPart, length, jni::make_jstring(label), context.has_value() ? JArrayBuffer::wrap(context.value()) : nullptr);
    return __result != nullptr ? std::make_optional(__result->cthis()->getArrayBuffer()) : std::nullopt;
  }
  void JHybridNetSocketDriverSpec::setNoDelay(bool enable) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jboolean /* enable */)>("setNoDelay");
    method(_javaPart, enable);
  }
  void JHybridNetSocketDriverSpec::setKeepAlive(bool enable, double delay) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jboolean /* enable */, double /* delay */)>("setKeepAlive");
    method(_javaPart, enable, delay);
  }
  std::string JHybridNetSocketDriverSpec::getLocalAddress() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getLocalAddress");
    auto __result = method(_javaPart);
    return __result->toStdString();
  }
  std::string JHybridNetSocketDriverSpec::getRemoteAddress() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getRemoteAddress");
    auto __result = method(_javaPart);
    return __result->toStdString();
  }

} // namespace margelo::nitro::net
