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

#include "JHybridMunimBluetoothSpec.hpp"

// Forward declaration of `AdvertisingDataTypes` to properly resolve imports.
namespace margelo::nitro::munimbluetooth { struct AdvertisingDataTypes; }
// Forward declaration of `ServiceDataEntry` to properly resolve imports.
namespace margelo::nitro::munimbluetooth { struct ServiceDataEntry; }
// Forward declaration of `GATTService` to properly resolve imports.
namespace margelo::nitro::munimbluetooth { struct GATTService; }
// Forward declaration of `GATTCharacteristic` to properly resolve imports.
namespace margelo::nitro::munimbluetooth { struct GATTCharacteristic; }
// Forward declaration of `CharacteristicValue` to properly resolve imports.
namespace margelo::nitro::munimbluetooth { struct CharacteristicValue; }
// Forward declaration of `AdvertisingOptions` to properly resolve imports.
namespace margelo::nitro::munimbluetooth { struct AdvertisingOptions; }
// Forward declaration of `ScanOptions` to properly resolve imports.
namespace margelo::nitro::munimbluetooth { struct ScanOptions; }
// Forward declaration of `ScanMode` to properly resolve imports.
namespace margelo::nitro::munimbluetooth { enum class ScanMode; }
// Forward declaration of `WriteType` to properly resolve imports.
namespace margelo::nitro::munimbluetooth { enum class WriteType; }

#include "AdvertisingDataTypes.hpp"
#include <NitroModules/Promise.hpp>
#include <NitroModules/JPromise.hpp>
#include "JAdvertisingDataTypes.hpp"
#include <optional>
#include <string>
#include <vector>
#include "ServiceDataEntry.hpp"
#include "JServiceDataEntry.hpp"
#include <NitroModules/JUnit.hpp>
#include "GATTService.hpp"
#include "JGATTService.hpp"
#include "GATTCharacteristic.hpp"
#include "JGATTCharacteristic.hpp"
#include "CharacteristicValue.hpp"
#include "JCharacteristicValue.hpp"
#include "AdvertisingOptions.hpp"
#include "JAdvertisingOptions.hpp"
#include "ScanOptions.hpp"
#include "JScanOptions.hpp"
#include "ScanMode.hpp"
#include "JScanMode.hpp"
#include "WriteType.hpp"
#include "JWriteType.hpp"

namespace margelo::nitro::munimbluetooth {

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

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

  size_t JHybridMunimBluetoothSpec::getExternalMemorySize() noexcept {
    static const auto method = javaClassStatic()->getMethod<jlong()>("getMemorySize");
    return method(_javaPart);
  }

  bool JHybridMunimBluetoothSpec::equals(const std::shared_ptr<HybridObject>& other) {
    if (auto otherCast = std::dynamic_pointer_cast<JHybridMunimBluetoothSpec>(other)) {
      return _javaPart == otherCast->_javaPart;
    }
    return false;
  }

  void JHybridMunimBluetoothSpec::dispose() noexcept {
    static const auto method = javaClassStatic()->getMethod<void()>("dispose");
    method(_javaPart);
  }

  std::string JHybridMunimBluetoothSpec::toString() {
    static const auto method = javaClassStatic()->getMethod<jni::JString()>("toString");
    auto javaString = method(_javaPart);
    return javaString->toStdString();
  }

  // Properties
  

  // Methods
  void JHybridMunimBluetoothSpec::startAdvertising(const AdvertisingOptions& options) {
    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JAdvertisingOptions> /* options */)>("startAdvertising");
    method(_javaPart, JAdvertisingOptions::fromCpp(options));
  }
  void JHybridMunimBluetoothSpec::updateAdvertisingData(const AdvertisingDataTypes& advertisingData) {
    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JAdvertisingDataTypes> /* advertisingData */)>("updateAdvertisingData");
    method(_javaPart, JAdvertisingDataTypes::fromCpp(advertisingData));
  }
  std::shared_ptr<Promise<AdvertisingDataTypes>> JHybridMunimBluetoothSpec::getAdvertisingData() {
    static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("getAdvertisingData");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<AdvertisingDataTypes>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<JAdvertisingDataTypes>(__boxedResult);
        __promise->resolve(__result->toCpp());
      });
      __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
        jni::JniException __jniError(__throwable);
        __promise->reject(std::make_exception_ptr(__jniError));
      });
      return __promise;
    }();
  }
  void JHybridMunimBluetoothSpec::stopAdvertising() {
    static const auto method = javaClassStatic()->getMethod<void()>("stopAdvertising");
    method(_javaPart);
  }
  void JHybridMunimBluetoothSpec::setServices(const std::vector<GATTService>& services) {
    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JArrayClass<JGATTService>> /* services */)>("setServices");
    method(_javaPart, [&]() {
      size_t __size = services.size();
      jni::local_ref<jni::JArrayClass<JGATTService>> __array = jni::JArrayClass<JGATTService>::newArray(__size);
      for (size_t __i = 0; __i < __size; __i++) {
        const auto& __element = services[__i];
        auto __elementJni = JGATTService::fromCpp(__element);
        __array->setElement(__i, *__elementJni);
      }
      return __array;
    }());
  }
  std::shared_ptr<Promise<bool>> JHybridMunimBluetoothSpec::isBluetoothEnabled() {
    static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("isBluetoothEnabled");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<bool>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JBoolean>(__boxedResult);
        __promise->resolve(static_cast<bool>(__result->value()));
      });
      __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
        jni::JniException __jniError(__throwable);
        __promise->reject(std::make_exception_ptr(__jniError));
      });
      return __promise;
    }();
  }
  std::shared_ptr<Promise<bool>> JHybridMunimBluetoothSpec::requestBluetoothPermission() {
    static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("requestBluetoothPermission");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<bool>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JBoolean>(__boxedResult);
        __promise->resolve(static_cast<bool>(__result->value()));
      });
      __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
        jni::JniException __jniError(__throwable);
        __promise->reject(std::make_exception_ptr(__jniError));
      });
      return __promise;
    }();
  }
  void JHybridMunimBluetoothSpec::startScan(const std::optional<ScanOptions>& options) {
    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<JScanOptions> /* options */)>("startScan");
    method(_javaPart, options.has_value() ? JScanOptions::fromCpp(options.value()) : nullptr);
  }
  void JHybridMunimBluetoothSpec::stopScan() {
    static const auto method = javaClassStatic()->getMethod<void()>("stopScan");
    method(_javaPart);
  }
  std::shared_ptr<Promise<void>> JHybridMunimBluetoothSpec::connect(const std::string& deviceId) {
    static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* deviceId */)>("connect");
    auto __result = method(_javaPart, jni::make_jstring(deviceId));
    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;
    }();
  }
  void JHybridMunimBluetoothSpec::disconnect(const std::string& deviceId) {
    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */)>("disconnect");
    method(_javaPart, jni::make_jstring(deviceId));
  }
  std::shared_ptr<Promise<std::vector<GATTService>>> JHybridMunimBluetoothSpec::discoverServices(const std::string& deviceId) {
    static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* deviceId */)>("discoverServices");
    auto __result = method(_javaPart, jni::make_jstring(deviceId));
    return [&]() {
      auto __promise = Promise<std::vector<GATTService>>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JArrayClass<JGATTService>>(__boxedResult);
        __promise->resolve([&]() {
          size_t __size = __result->size();
          std::vector<GATTService> __vector;
          __vector.reserve(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            auto __element = __result->getElement(__i);
            __vector.push_back(__element->toCpp());
          }
          return __vector;
        }());
      });
      __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
        jni::JniException __jniError(__throwable);
        __promise->reject(std::make_exception_ptr(__jniError));
      });
      return __promise;
    }();
  }
  std::shared_ptr<Promise<CharacteristicValue>> JHybridMunimBluetoothSpec::readCharacteristic(const std::string& deviceId, const std::string& serviceUUID, const std::string& characteristicUUID) {
    static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<jni::JString> /* serviceUUID */, jni::alias_ref<jni::JString> /* characteristicUUID */)>("readCharacteristic");
    auto __result = method(_javaPart, jni::make_jstring(deviceId), jni::make_jstring(serviceUUID), jni::make_jstring(characteristicUUID));
    return [&]() {
      auto __promise = Promise<CharacteristicValue>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<JCharacteristicValue>(__boxedResult);
        __promise->resolve(__result->toCpp());
      });
      __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
        jni::JniException __jniError(__throwable);
        __promise->reject(std::make_exception_ptr(__jniError));
      });
      return __promise;
    }();
  }
  std::shared_ptr<Promise<void>> JHybridMunimBluetoothSpec::writeCharacteristic(const std::string& deviceId, const std::string& serviceUUID, const std::string& characteristicUUID, const std::string& value, std::optional<WriteType> writeType) {
    static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<jni::JString> /* serviceUUID */, jni::alias_ref<jni::JString> /* characteristicUUID */, jni::alias_ref<jni::JString> /* value */, jni::alias_ref<JWriteType> /* writeType */)>("writeCharacteristic");
    auto __result = method(_javaPart, jni::make_jstring(deviceId), jni::make_jstring(serviceUUID), jni::make_jstring(characteristicUUID), jni::make_jstring(value), writeType.has_value() ? JWriteType::fromCpp(writeType.value()) : nullptr);
    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;
    }();
  }
  void JHybridMunimBluetoothSpec::subscribeToCharacteristic(const std::string& deviceId, const std::string& serviceUUID, const std::string& characteristicUUID) {
    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<jni::JString> /* serviceUUID */, jni::alias_ref<jni::JString> /* characteristicUUID */)>("subscribeToCharacteristic");
    method(_javaPart, jni::make_jstring(deviceId), jni::make_jstring(serviceUUID), jni::make_jstring(characteristicUUID));
  }
  void JHybridMunimBluetoothSpec::unsubscribeFromCharacteristic(const std::string& deviceId, const std::string& serviceUUID, const std::string& characteristicUUID) {
    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* deviceId */, jni::alias_ref<jni::JString> /* serviceUUID */, jni::alias_ref<jni::JString> /* characteristicUUID */)>("unsubscribeFromCharacteristic");
    method(_javaPart, jni::make_jstring(deviceId), jni::make_jstring(serviceUUID), jni::make_jstring(characteristicUUID));
  }
  std::shared_ptr<Promise<std::vector<std::string>>> JHybridMunimBluetoothSpec::getConnectedDevices() {
    static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("getConnectedDevices");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<std::vector<std::string>>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JArrayClass<jni::JString>>(__boxedResult);
        __promise->resolve([&]() {
          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;
        }());
      });
      __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
        jni::JniException __jniError(__throwable);
        __promise->reject(std::make_exception_ptr(__jniError));
      });
      return __promise;
    }();
  }
  std::shared_ptr<Promise<double>> JHybridMunimBluetoothSpec::readRSSI(const std::string& deviceId) {
    static const auto method = javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* deviceId */)>("readRSSI");
    auto __result = method(_javaPart, jni::make_jstring(deviceId));
    return [&]() {
      auto __promise = Promise<double>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JDouble>(__boxedResult);
        __promise->resolve(__result->value());
      });
      __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
        jni::JniException __jniError(__throwable);
        __promise->reject(std::make_exception_ptr(__jniError));
      });
      return __promise;
    }();
  }
  void JHybridMunimBluetoothSpec::addListener(const std::string& eventName) {
    static const auto method = javaClassStatic()->getMethod<void(jni::alias_ref<jni::JString> /* eventName */)>("addListener");
    method(_javaPart, jni::make_jstring(eventName));
  }
  void JHybridMunimBluetoothSpec::removeListeners(double count) {
    static const auto method = javaClassStatic()->getMethod<void(double /* count */)>("removeListeners");
    method(_javaPart, count);
  }

} // namespace margelo::nitro::munimbluetooth
