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

#include "JHybridEspProvToolkitSpec.hpp"

// Forward declaration of `PTSearchResult` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { struct PTSearchResult; }
// Forward declaration of `PTResult` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { struct PTResult; }
// Forward declaration of `PTDeviceResult` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { struct PTDeviceResult; }
// Forward declaration of `PTDevice` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { struct PTDevice; }
// Forward declaration of `PTSecurity` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { enum class PTSecurity; }
// Forward declaration of `PTTransport` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { enum class PTTransport; }
// Forward declaration of `PTWifiScanResult` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { struct PTWifiScanResult; }
// Forward declaration of `PTWifiEntry` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { struct PTWifiEntry; }
// Forward declaration of `PTSessionResult` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { struct PTSessionResult; }
// Forward declaration of `PTSessionStatus` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { enum class PTSessionStatus; }
// Forward declaration of `PTProvisionResult` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { struct PTProvisionResult; }
// Forward declaration of `PTBooleanResult` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { struct PTBooleanResult; }
// Forward declaration of `PTStringResult` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { struct PTStringResult; }
// Forward declaration of `PTLocationAccess` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { enum class PTLocationAccess; }
// Forward declaration of `PTError` to properly resolve imports.
namespace margelo::nitro::espprovtoolkit { enum class PTError; }

#include "PTSearchResult.hpp"
#include <NitroModules/Promise.hpp>
#include <NitroModules/JPromise.hpp>
#include "JPTSearchResult.hpp"
#include <string>
#include <vector>
#include <optional>
#include "PTResult.hpp"
#include "JPTResult.hpp"
#include "PTDeviceResult.hpp"
#include "JPTDeviceResult.hpp"
#include "PTDevice.hpp"
#include "JPTDevice.hpp"
#include "PTSecurity.hpp"
#include "JPTSecurity.hpp"
#include "PTTransport.hpp"
#include "JPTTransport.hpp"
#include "PTWifiScanResult.hpp"
#include "JPTWifiScanResult.hpp"
#include "PTWifiEntry.hpp"
#include "JPTWifiEntry.hpp"
#include "PTSessionResult.hpp"
#include "JPTSessionResult.hpp"
#include "PTSessionStatus.hpp"
#include "JPTSessionStatus.hpp"
#include "PTProvisionResult.hpp"
#include "JPTProvisionResult.hpp"
#include "PTBooleanResult.hpp"
#include "JPTBooleanResult.hpp"
#include "PTStringResult.hpp"
#include "JPTStringResult.hpp"
#include "PTLocationAccess.hpp"
#include "JPTLocationAccess.hpp"
#include <functional>
#include "JFunc_std__shared_ptr_Promise_bool___PTLocationAccess.hpp"
#include <NitroModules/JNICallable.hpp>
#include "PTError.hpp"
#include "JPTError.hpp"

namespace margelo::nitro::espprovtoolkit {

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

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

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

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

  // Properties
  

  // Methods
  std::shared_ptr<Promise<PTSearchResult>> JHybridEspProvToolkitSpec::searchForESPDevices(const std::string& devicePrefix, PTTransport transport, PTSecurity security) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* devicePrefix */, jni::alias_ref<JPTTransport> /* transport */, jni::alias_ref<JPTSecurity> /* security */)>("searchForESPDevices");
    auto __result = method(_javaPart, jni::make_jstring(devicePrefix), JPTTransport::fromCpp(transport), JPTSecurity::fromCpp(security));
    return [&]() {
      auto __promise = Promise<PTSearchResult>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<JPTSearchResult>(__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 JHybridEspProvToolkitSpec::stopSearchingForESPDevices() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("stopSearchingForESPDevices");
    method(_javaPart);
  }
  std::shared_ptr<Promise<PTResult>> JHybridEspProvToolkitSpec::createESPDevice(const std::string& deviceName, PTTransport transport, PTSecurity security, const std::optional<std::string>& proofOfPossession, const std::optional<std::string>& softAPPassword, const std::optional<std::string>& username) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* deviceName */, jni::alias_ref<JPTTransport> /* transport */, jni::alias_ref<JPTSecurity> /* security */, jni::alias_ref<jni::JString> /* proofOfPossession */, jni::alias_ref<jni::JString> /* softAPPassword */, jni::alias_ref<jni::JString> /* username */)>("createESPDevice");
    auto __result = method(_javaPart, jni::make_jstring(deviceName), JPTTransport::fromCpp(transport), JPTSecurity::fromCpp(security), proofOfPossession.has_value() ? jni::make_jstring(proofOfPossession.value()) : nullptr, softAPPassword.has_value() ? jni::make_jstring(softAPPassword.value()) : nullptr, username.has_value() ? jni::make_jstring(username.value()) : nullptr);
    return [&]() {
      auto __promise = Promise<PTResult>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<JPTResult>(__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;
    }();
  }
  PTDeviceResult JHybridEspProvToolkitSpec::getESPDevice(const std::string& deviceName) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPTDeviceResult>(jni::alias_ref<jni::JString> /* deviceName */)>("getESPDevice");
    auto __result = method(_javaPart, jni::make_jstring(deviceName));
    return __result->toCpp();
  }
  bool JHybridEspProvToolkitSpec::doesESPDeviceExist(const std::string& deviceName) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean(jni::alias_ref<jni::JString> /* deviceName */)>("doesESPDeviceExist");
    auto __result = method(_javaPart, jni::make_jstring(deviceName));
    return static_cast<bool>(__result);
  }
  std::shared_ptr<Promise<PTWifiScanResult>> JHybridEspProvToolkitSpec::scanWifiListOfESPDevice(const std::string& deviceName) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* deviceName */)>("scanWifiListOfESPDevice");
    auto __result = method(_javaPart, jni::make_jstring(deviceName));
    return [&]() {
      auto __promise = Promise<PTWifiScanResult>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<JPTWifiScanResult>(__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<PTSessionResult>> JHybridEspProvToolkitSpec::connectToESPDevice(const std::string& deviceName) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* deviceName */)>("connectToESPDevice");
    auto __result = method(_javaPart, jni::make_jstring(deviceName));
    return [&]() {
      auto __promise = Promise<PTSessionResult>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<JPTSessionResult>(__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;
    }();
  }
  PTResult JHybridEspProvToolkitSpec::disconnectFromESPDevice(const std::string& deviceName) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPTResult>(jni::alias_ref<jni::JString> /* deviceName */)>("disconnectFromESPDevice");
    auto __result = method(_javaPart, jni::make_jstring(deviceName));
    return __result->toCpp();
  }
  std::shared_ptr<Promise<PTProvisionResult>> JHybridEspProvToolkitSpec::provisionESPDevice(const std::string& deviceName, const std::string& ssid, const std::string& password) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* deviceName */, jni::alias_ref<jni::JString> /* ssid */, jni::alias_ref<jni::JString> /* password */)>("provisionESPDevice");
    auto __result = method(_javaPart, jni::make_jstring(deviceName), jni::make_jstring(ssid), jni::make_jstring(password));
    return [&]() {
      auto __promise = Promise<PTProvisionResult>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<JPTProvisionResult>(__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;
    }();
  }
  PTBooleanResult JHybridEspProvToolkitSpec::isESPDeviceSessionEstablished(const std::string& deviceName) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPTBooleanResult>(jni::alias_ref<jni::JString> /* deviceName */)>("isESPDeviceSessionEstablished");
    auto __result = method(_javaPart, jni::make_jstring(deviceName));
    return __result->toCpp();
  }
  std::shared_ptr<Promise<PTStringResult>> JHybridEspProvToolkitSpec::sendDataToESPDevice(const std::string& deviceName, const std::string& path, const std::string& data) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* deviceName */, jni::alias_ref<jni::JString> /* path */, jni::alias_ref<jni::JString> /* data */)>("sendDataToESPDevice");
    auto __result = method(_javaPart, jni::make_jstring(deviceName), jni::make_jstring(path), jni::make_jstring(data));
    return [&]() {
      auto __promise = Promise<PTStringResult>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<JPTStringResult>(__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;
    }();
  }
  PTStringResult JHybridEspProvToolkitSpec::getIPv4AddressOfESPDevice(const std::string& deviceName) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPTStringResult>(jni::alias_ref<jni::JString> /* deviceName */)>("getIPv4AddressOfESPDevice");
    auto __result = method(_javaPart, jni::make_jstring(deviceName));
    return __result->toCpp();
  }
  std::shared_ptr<Promise<PTStringResult>> JHybridEspProvToolkitSpec::getCurrentNetworkSSID() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("getCurrentNetworkSSID");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<PTStringResult>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<JPTStringResult>(__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 JHybridEspProvToolkitSpec::requestLocationPermission() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("requestLocationPermission");
    method(_javaPart);
  }
  double JHybridEspProvToolkitSpec::registerLocationStatusCallback(const std::function<std::shared_ptr<Promise<bool>>(PTLocationAccess /* level */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<double(jni::alias_ref<JFunc_std__shared_ptr_Promise_bool___PTLocationAccess::javaobject> /* callback */)>("registerLocationStatusCallback_cxx");
    auto __result = method(_javaPart, JFunc_std__shared_ptr_Promise_bool___PTLocationAccess_cxx::fromCpp(callback));
    return __result;
  }
  bool JHybridEspProvToolkitSpec::removeLocationStatusCallback(double id) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean(double /* id */)>("removeLocationStatusCallback");
    auto __result = method(_javaPart, id);
    return static_cast<bool>(__result);
  }
  PTLocationAccess JHybridEspProvToolkitSpec::getCurrentLocationStatus() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPTLocationAccess>()>("getCurrentLocationStatus");
    auto __result = method(_javaPart);
    return __result->toCpp();
  }
  double JHybridEspProvToolkitSpec::nativeErrorToNumber(PTError error) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<double(jni::alias_ref<JPTError> /* error */)>("nativeErrorToNumber");
    auto __result = method(_javaPart, JPTError::fromCpp(error));
    return __result;
  }

} // namespace margelo::nitro::espprovtoolkit
