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

#include "JHybridNativeBleNitroSpec.hpp"

// Forward declaration of `BLEDevice` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { struct BLEDevice; }
// Forward declaration of `ManufacturerData` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { struct ManufacturerData; }
// Forward declaration of `ManufacturerDataEntry` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { struct ManufacturerDataEntry; }
// Forward declaration of `ServiceData` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { struct ServiceData; }
// Forward declaration of `ServiceDataEntry` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { struct ServiceDataEntry; }
// Forward declaration of `BLEState` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { enum class BLEState; }
// Forward declaration of `OperationResult` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { struct OperationResult; }
// Forward declaration of `ScanFilter` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { struct ScanFilter; }
// Forward declaration of `AndroidScanMode` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { enum class AndroidScanMode; }
// Forward declaration of `AndroidConnectionPriority` to properly resolve imports.
namespace margelo::nitro::co::zyke::ble { enum class AndroidConnectionPriority; }

#include <string>
#include <optional>
#include "BLEDevice.hpp"
#include <vector>
#include "JBLEDevice.hpp"
#include "ManufacturerData.hpp"
#include "JManufacturerData.hpp"
#include "ManufacturerDataEntry.hpp"
#include "JManufacturerDataEntry.hpp"
#include <NitroModules/ArrayBuffer.hpp>
#include <NitroModules/JArrayBuffer.hpp>
#include "ServiceData.hpp"
#include "JServiceData.hpp"
#include "ServiceDataEntry.hpp"
#include "JServiceDataEntry.hpp"
#include "BLEState.hpp"
#include "JBLEState.hpp"
#include "OperationResult.hpp"
#include "JOperationResult.hpp"
#include <NitroModules/Promise.hpp>
#include <NitroModules/JPromise.hpp>
#include <NitroModules/JUnit.hpp>
#include <functional>
#include "JFunc_void_std__vector_BLEDevice_.hpp"
#include <NitroModules/JNICallable.hpp>
#include "ScanFilter.hpp"
#include "JScanFilter.hpp"
#include "AndroidScanMode.hpp"
#include "JAndroidScanMode.hpp"
#include <NitroModules/Null.hpp>
#include <variant>
#include "JFunc_void_std__optional_std__variant_nitro__NullType__BLEDevice___std__optional_std__variant_nitro__NullType__std__string__.hpp"
#include "JVariant_NullType_BLEDevice.hpp"
#include <NitroModules/JNull.hpp>
#include "JVariant_NullType_String.hpp"
#include "JFunc_void_bool_std__string_std__string.hpp"
#include "JFunc_void_std__string_bool_std__string.hpp"
#include "JFunc_void_bool_std__string.hpp"
#include "AndroidConnectionPriority.hpp"
#include "JAndroidConnectionPriority.hpp"
#include "JFunc_void_bool_double_std__string.hpp"
#include "JFunc_void_bool_std__shared_ptr_ArrayBuffer__std__string.hpp"
#include "JFunc_void_std__string_std__shared_ptr_ArrayBuffer_.hpp"
#include "JFunc_void_BLEState.hpp"

namespace margelo::nitro::co::zyke::ble {

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

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

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

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

  // Properties
  std::optional<std::string> JHybridNativeBleNitroSpec::getRestoreStateIdentifier() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>()>("getRestoreStateIdentifier");
    auto __result = method(_javaPart);
    return __result != nullptr ? std::make_optional(__result->toStdString()) : std::nullopt;
  }
  void JHybridNativeBleNitroSpec::setRestoreStateIdentifier(const std::optional<std::string>& restoreStateIdentifier) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* restoreStateIdentifier */)>("setRestoreStateIdentifier");
    method(_javaPart, restoreStateIdentifier.has_value() ? jni::make_jstring(restoreStateIdentifier.value()) : nullptr);
  }

  // Methods
  void JHybridNativeBleNitroSpec::setRestoreStateCallback(const std::function<void(const std::vector<BLEDevice>& /* restoredPeripherals */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_std__vector_BLEDevice_::javaobject> /* callback */)>("setRestoreStateCallback_cxx");
    method(_javaPart, JFunc_void_std__vector_BLEDevice__cxx::fromCpp(callback));
  }
  void JHybridNativeBleNitroSpec::iosLazyInit() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("iosLazyInit");
    method(_javaPart);
  }
  void JHybridNativeBleNitroSpec::startScan(const ScanFilter& filter, const std::function<void(const std::optional<std::variant<nitro::NullType, BLEDevice>>& /* device */, const std::optional<std::variant<nitro::NullType, std::string>>& /* error */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JScanFilter> /* filter */, jni::alias_ref<JFunc_void_std__optional_std__variant_nitro__NullType__BLEDevice___std__optional_std__variant_nitro__NullType__std__string__::javaobject> /* callback */)>("startScan_cxx");
    method(_javaPart, JScanFilter::fromCpp(filter), JFunc_void_std__optional_std__variant_nitro__NullType__BLEDevice___std__optional_std__variant_nitro__NullType__std__string___cxx::fromCpp(callback));
  }
  bool JHybridNativeBleNitroSpec::stopScan() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("stopScan");
    auto __result = method(_javaPart);
    return static_cast<bool>(__result);
  }
  bool JHybridNativeBleNitroSpec::isScanning() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("isScanning");
    auto __result = method(_javaPart);
    return static_cast<bool>(__result);
  }
  std::vector<BLEDevice> JHybridNativeBleNitroSpec::getConnectedDevices(const std::vector<std::string>& services) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JArrayClass<JBLEDevice>>(jni::alias_ref<jni::JArrayClass<jni::JString>> /* services */)>("getConnectedDevices");
    auto __result = method(_javaPart, [&]() {
      size_t __size = services.size();
      jni::local_ref<jni::JArrayClass<jni::JString>> __array = jni::JArrayClass<jni::JString>::newArray(__size);
      for (size_t __i = 0; __i < __size; __i++) {
        const auto& __element = services[__i];
        auto __elementJni = jni::make_jstring(__element);
        __array->setElement(__i, *__elementJni);
      }
      return __array;
    }());
    return [&]() {
      size_t __size = __result->size();
      std::vector<BLEDevice> __vector;
      __vector.reserve(__size);
      for (size_t __i = 0; __i < __size; __i++) {
        auto __element = __result->getElement(__i);
        __vector.push_back(__element->toCpp());
      }
      return __vector;
    }();
  }
  void JHybridNativeBleNitroSpec::connect(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* deviceId */, const std::string& /* error */)>& callback, const std::optional<std::function<void(const std::string& /* deviceId */, bool /* interrupted */, const std::string& /* error */)>>& disconnectCallback, std::optional<bool> autoConnectAndroid) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<JFunc_void_bool_std__string_std__string::javaobject> /* callback */, jni::alias_ref<JFunc_void_std__string_bool_std__string::javaobject> /* disconnectCallback */, jni::alias_ref<jni::JBoolean> /* autoConnectAndroid */)>("connect_cxx");
    method(_javaPart, jni::make_jstring(deviceId), JFunc_void_bool_std__string_std__string_cxx::fromCpp(callback), disconnectCallback.has_value() ? JFunc_void_std__string_bool_std__string_cxx::fromCpp(disconnectCallback.value()) : nullptr, autoConnectAndroid.has_value() ? jni::JBoolean::valueOf(autoConnectAndroid.value()) : nullptr);
  }
  void JHybridNativeBleNitroSpec::disconnect(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<JFunc_void_bool_std__string::javaobject> /* callback */)>("disconnect_cxx");
    method(_javaPart, jni::make_jstring(deviceId), JFunc_void_bool_std__string_cxx::fromCpp(callback));
  }
  bool JHybridNativeBleNitroSpec::isConnected(const std::string& deviceId) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean(jni::alias_ref<jni::JString> /* deviceId */)>("isConnected");
    auto __result = method(_javaPart, jni::make_jstring(deviceId));
    return static_cast<bool>(__result);
  }
  double JHybridNativeBleNitroSpec::requestMTU(const std::string& deviceId, double mtu) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<double(jni::alias_ref<jni::JString> /* deviceId */, double /* mtu */)>("requestMTU");
    auto __result = method(_javaPart, jni::make_jstring(deviceId), mtu);
    return __result;
  }
  bool JHybridNativeBleNitroSpec::requestConnectionPriority(const std::string& deviceId, AndroidConnectionPriority androidConnectionPriority) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<JAndroidConnectionPriority> /* androidConnectionPriority */)>("requestConnectionPriority");
    auto __result = method(_javaPart, jni::make_jstring(deviceId), JAndroidConnectionPriority::fromCpp(androidConnectionPriority));
    return static_cast<bool>(__result);
  }
  void JHybridNativeBleNitroSpec::readRSSI(const std::string& deviceId, const std::function<void(bool /* success */, double /* rssi */, const std::string& /* error */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<JFunc_void_bool_double_std__string::javaobject> /* callback */)>("readRSSI_cxx");
    method(_javaPart, jni::make_jstring(deviceId), JFunc_void_bool_double_std__string_cxx::fromCpp(callback));
  }
  void JHybridNativeBleNitroSpec::discoverServices(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<JFunc_void_bool_std__string::javaobject> /* callback */)>("discoverServices_cxx");
    method(_javaPart, jni::make_jstring(deviceId), JFunc_void_bool_std__string_cxx::fromCpp(callback));
  }
  void JHybridNativeBleNitroSpec::discoverServicesWithCharacteristics(const std::string& deviceId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<JFunc_void_bool_std__string::javaobject> /* callback */)>("discoverServicesWithCharacteristics_cxx");
    method(_javaPart, jni::make_jstring(deviceId), JFunc_void_bool_std__string_cxx::fromCpp(callback));
  }
  std::vector<std::string> JHybridNativeBleNitroSpec::getServices(const std::string& deviceId) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JArrayClass<jni::JString>>(jni::alias_ref<jni::JString> /* deviceId */)>("getServices");
    auto __result = method(_javaPart, jni::make_jstring(deviceId));
    return [&]() {
      size_t __size = __result->size();
      std::vector<std::string> __vector;
      __vector.reserve(__size);
      for (size_t __i = 0; __i < __size; __i++) {
        auto __element = __result->getElement(__i);
        __vector.push_back(__element->toStdString());
      }
      return __vector;
    }();
  }
  std::vector<std::string> JHybridNativeBleNitroSpec::getCharacteristics(const std::string& deviceId, const std::string& serviceId) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JArrayClass<jni::JString>>(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<jni::JString> /* serviceId */)>("getCharacteristics");
    auto __result = method(_javaPart, jni::make_jstring(deviceId), jni::make_jstring(serviceId));
    return [&]() {
      size_t __size = __result->size();
      std::vector<std::string> __vector;
      __vector.reserve(__size);
      for (size_t __i = 0; __i < __size; __i++) {
        auto __element = __result->getElement(__i);
        __vector.push_back(__element->toStdString());
      }
      return __vector;
    }();
  }
  void JHybridNativeBleNitroSpec::readCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::function<void(bool /* success */, const std::shared_ptr<ArrayBuffer>& /* data */, const std::string& /* error */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<jni::JString> /* serviceId */, jni::alias_ref<jni::JString> /* characteristicId */, jni::alias_ref<JFunc_void_bool_std__shared_ptr_ArrayBuffer__std__string::javaobject> /* callback */)>("readCharacteristic_cxx");
    method(_javaPart, jni::make_jstring(deviceId), jni::make_jstring(serviceId), jni::make_jstring(characteristicId), JFunc_void_bool_std__shared_ptr_ArrayBuffer__std__string_cxx::fromCpp(callback));
  }
  void JHybridNativeBleNitroSpec::writeCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::shared_ptr<ArrayBuffer>& data, bool withResponse, const std::function<void(bool /* success */, const std::shared_ptr<ArrayBuffer>& /* responseData */, const std::string& /* error */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<jni::JString> /* serviceId */, jni::alias_ref<jni::JString> /* characteristicId */, jni::alias_ref<JArrayBuffer::javaobject> /* data */, jboolean /* withResponse */, jni::alias_ref<JFunc_void_bool_std__shared_ptr_ArrayBuffer__std__string::javaobject> /* callback */)>("writeCharacteristic_cxx");
    method(_javaPart, jni::make_jstring(deviceId), jni::make_jstring(serviceId), jni::make_jstring(characteristicId), JArrayBuffer::wrap(data), withResponse, JFunc_void_bool_std__shared_ptr_ArrayBuffer__std__string_cxx::fromCpp(callback));
  }
  void JHybridNativeBleNitroSpec::subscribeToCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::function<void(const std::string& /* characteristicId */, const std::shared_ptr<ArrayBuffer>& /* data */)>& updateCallback, const std::function<void(bool /* success */, const std::string& /* error */)>& completionCallback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<jni::JString> /* serviceId */, jni::alias_ref<jni::JString> /* characteristicId */, jni::alias_ref<JFunc_void_std__string_std__shared_ptr_ArrayBuffer_::javaobject> /* updateCallback */, jni::alias_ref<JFunc_void_bool_std__string::javaobject> /* completionCallback */)>("subscribeToCharacteristic_cxx");
    method(_javaPart, jni::make_jstring(deviceId), jni::make_jstring(serviceId), jni::make_jstring(characteristicId), JFunc_void_std__string_std__shared_ptr_ArrayBuffer__cxx::fromCpp(updateCallback), JFunc_void_bool_std__string_cxx::fromCpp(completionCallback));
  }
  void JHybridNativeBleNitroSpec::unsubscribeFromCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId, const std::function<void(bool /* success */, const std::string& /* error */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<jni::JString> /* serviceId */, jni::alias_ref<jni::JString> /* characteristicId */, jni::alias_ref<JFunc_void_bool_std__string::javaobject> /* callback */)>("unsubscribeFromCharacteristic_cxx");
    method(_javaPart, jni::make_jstring(deviceId), jni::make_jstring(serviceId), jni::make_jstring(characteristicId), JFunc_void_bool_std__string_cxx::fromCpp(callback));
  }
  bool JHybridNativeBleNitroSpec::isSubscribedToCharacteristic(const std::string& deviceId, const std::string& serviceId, const std::string& characteristicId) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<jni::JString> /* serviceId */, jni::alias_ref<jni::JString> /* characteristicId */)>("isSubscribedToCharacteristic");
    auto __result = method(_javaPart, jni::make_jstring(deviceId), jni::make_jstring(serviceId), jni::make_jstring(characteristicId));
    return static_cast<bool>(__result);
  }
  void JHybridNativeBleNitroSpec::requestBluetoothEnable(const std::function<void(bool /* success */, const std::string& /* error */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_bool_std__string::javaobject> /* callback */)>("requestBluetoothEnable_cxx");
    method(_javaPart, JFunc_void_bool_std__string_cxx::fromCpp(callback));
  }
  BLEState JHybridNativeBleNitroSpec::state() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JBLEState>()>("state");
    auto __result = method(_javaPart);
    return __result->toCpp();
  }
  OperationResult JHybridNativeBleNitroSpec::subscribeToStateChange(const std::function<void(BLEState /* state */)>& stateCallback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JOperationResult>(jni::alias_ref<JFunc_void_BLEState::javaobject> /* stateCallback */)>("subscribeToStateChange_cxx");
    auto __result = method(_javaPart, JFunc_void_BLEState_cxx::fromCpp(stateCallback));
    return __result->toCpp();
  }
  OperationResult JHybridNativeBleNitroSpec::unsubscribeFromStateChange() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JOperationResult>()>("unsubscribeFromStateChange");
    auto __result = method(_javaPart);
    return __result->toCpp();
  }
  std::shared_ptr<Promise<void>> JHybridNativeBleNitroSpec::openSettings() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("openSettings");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<void>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& /* unit */) {
        __promise->resolve();
      });
      __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
        jni::JniException __jniError(__throwable);
        __promise->reject(std::make_exception_ptr(__jniError));
      });
      return __promise;
    }();
  }

} // namespace margelo::nitro::co::zyke::ble
