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

#include "JHybridOneSpeechSpec.hpp"

// Forward declaration of `SpeechPermissionResponse` to properly resolve imports.
namespace margelo::nitro::one { struct SpeechPermissionResponse; }
// Forward declaration of `SpeechPermissionStatus` to properly resolve imports.
namespace margelo::nitro::one { enum class SpeechPermissionStatus; }
// Forward declaration of `SpeechStartOptions` to properly resolve imports.
namespace margelo::nitro::one { struct SpeechStartOptions; }
// Forward declaration of `SpeechEvent` to properly resolve imports.
namespace margelo::nitro::one { struct SpeechEvent; }
// Forward declaration of `SpeechEventType` to properly resolve imports.
namespace margelo::nitro::one { enum class SpeechEventType; }
// Forward declaration of `SpeechErrorCode` to properly resolve imports.
namespace margelo::nitro::one { enum class SpeechErrorCode; }

#include "SpeechPermissionResponse.hpp"
#include <NitroModules/Promise.hpp>
#include <NitroModules/JPromise.hpp>
#include "JSpeechPermissionResponse.hpp"
#include "SpeechPermissionStatus.hpp"
#include "JSpeechPermissionStatus.hpp"
#include <optional>
#include "SpeechStartOptions.hpp"
#include "JSpeechStartOptions.hpp"
#include <string>
#include "SpeechEvent.hpp"
#include <functional>
#include "JFunc_void_SpeechEvent.hpp"
#include <NitroModules/JNICallable.hpp>
#include "JSpeechEvent.hpp"
#include "SpeechEventType.hpp"
#include "JSpeechEventType.hpp"
#include "SpeechErrorCode.hpp"
#include "JSpeechErrorCode.hpp"

namespace margelo::nitro::one {

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

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

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

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

  // Properties
  

  // Methods
  bool JHybridOneSpeechSpec::isAvailable() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jboolean()>("isAvailable");
    auto __result = method(_javaPart);
    return static_cast<bool>(__result);
  }
  std::shared_ptr<Promise<SpeechPermissionResponse>> JHybridOneSpeechSpec::getPermissions() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("getPermissions");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<SpeechPermissionResponse>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<JSpeechPermissionResponse>(__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<SpeechPermissionResponse>> JHybridOneSpeechSpec::requestPermissions() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("requestPermissions");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<SpeechPermissionResponse>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<JSpeechPermissionResponse>(__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 JHybridOneSpeechSpec::start(const SpeechStartOptions& options, const std::function<void(const SpeechEvent& /* event */)>& onEvent) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JSpeechStartOptions> /* options */, jni::alias_ref<JFunc_void_SpeechEvent::javaobject> /* onEvent */)>("start_cxx");
    method(_javaPart, JSpeechStartOptions::fromCpp(options), JFunc_void_SpeechEvent_cxx::fromCpp(onEvent));
  }
  void JHybridOneSpeechSpec::stop() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("stop");
    method(_javaPart);
  }
  void JHybridOneSpeechSpec::abort() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("abort");
    method(_javaPart);
  }

} // namespace margelo::nitro::one
