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

#include "JHybridSoundSpec.hpp"

// Forward declaration of `AudioSet` to properly resolve imports.
namespace margelo::nitro::sound { struct AudioSet; }
// Forward declaration of `AVEncoderAudioQualityIOSType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVEncoderAudioQualityIOSType; }
// Forward declaration of `AVModeIOSOption` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVModeIOSOption; }
// Forward declaration of `AVEncodingOption` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVEncodingOption; }
// Forward declaration of `AVLinearPCMBitDepthKeyIOSType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVLinearPCMBitDepthKeyIOSType; }
// Forward declaration of `AudioSourceAndroidType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AudioSourceAndroidType; }
// Forward declaration of `OutputFormatAndroidType` to properly resolve imports.
namespace margelo::nitro::sound { enum class OutputFormatAndroidType; }
// Forward declaration of `AudioEncoderAndroidType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AudioEncoderAndroidType; }
// Forward declaration of `AudioQualityType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AudioQualityType; }
// Forward declaration of `RecordBackType` to properly resolve imports.
namespace margelo::nitro::sound { struct RecordBackType; }
// Forward declaration of `PlayBackType` to properly resolve imports.
namespace margelo::nitro::sound { struct PlayBackType; }
// Forward declaration of `PlaybackEndType` to properly resolve imports.
namespace margelo::nitro::sound { struct PlaybackEndType; }

#include <string>
#include <NitroModules/Promise.hpp>
#include <NitroModules/JPromise.hpp>
#include <optional>
#include "AudioSet.hpp"
#include "JAudioSet.hpp"
#include "AVEncoderAudioQualityIOSType.hpp"
#include "JAVEncoderAudioQualityIOSType.hpp"
#include "AVModeIOSOption.hpp"
#include "JAVModeIOSOption.hpp"
#include "AVEncodingOption.hpp"
#include "JAVEncodingOption.hpp"
#include "AVLinearPCMBitDepthKeyIOSType.hpp"
#include "JAVLinearPCMBitDepthKeyIOSType.hpp"
#include "AudioSourceAndroidType.hpp"
#include "JAudioSourceAndroidType.hpp"
#include "OutputFormatAndroidType.hpp"
#include "JOutputFormatAndroidType.hpp"
#include "AudioEncoderAndroidType.hpp"
#include "JAudioEncoderAndroidType.hpp"
#include "AudioQualityType.hpp"
#include "JAudioQualityType.hpp"
#include <unordered_map>
#include "RecordBackType.hpp"
#include <functional>
#include "JFunc_void_RecordBackType.hpp"
#include <NitroModules/JNICallable.hpp>
#include "JRecordBackType.hpp"
#include "PlayBackType.hpp"
#include "JFunc_void_PlayBackType.hpp"
#include "JPlayBackType.hpp"
#include "PlaybackEndType.hpp"
#include "JFunc_void_PlaybackEndType.hpp"
#include "JPlaybackEndType.hpp"

namespace margelo::nitro::sound {

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

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

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

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

  // Properties
  

  // Methods
  std::shared_ptr<Promise<std::string>> JHybridSoundSpec::startRecorder(const std::optional<std::string>& uri, const std::optional<AudioSet>& audioSets, std::optional<bool> meteringEnabled) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* uri */, jni::alias_ref<JAudioSet> /* audioSets */, jni::alias_ref<jni::JBoolean> /* meteringEnabled */)>("startRecorder");
    auto __result = method(_javaPart, uri.has_value() ? jni::make_jstring(uri.value()) : nullptr, audioSets.has_value() ? JAudioSet::fromCpp(audioSets.value()) : nullptr, meteringEnabled.has_value() ? jni::JBoolean::valueOf(meteringEnabled.value()) : nullptr);
    return [&]() {
      auto __promise = Promise<std::string>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
        __promise->resolve(__result->toStdString());
      });
      __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<std::string>> JHybridSoundSpec::pauseRecorder() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("pauseRecorder");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<std::string>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
        __promise->resolve(__result->toStdString());
      });
      __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<std::string>> JHybridSoundSpec::resumeRecorder() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("resumeRecorder");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<std::string>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
        __promise->resolve(__result->toStdString());
      });
      __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<std::string>> JHybridSoundSpec::stopRecorder() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("stopRecorder");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<std::string>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
        __promise->resolve(__result->toStdString());
      });
      __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<std::string>> JHybridSoundSpec::startPlayer(const std::optional<std::string>& uri, const std::optional<std::unordered_map<std::string, std::string>>& httpHeaders) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(jni::alias_ref<jni::JString> /* uri */, jni::alias_ref<jni::JMap<jni::JString, jni::JString>> /* httpHeaders */)>("startPlayer");
    auto __result = method(_javaPart, uri.has_value() ? jni::make_jstring(uri.value()) : nullptr, httpHeaders.has_value() ? [&]() -> jni::local_ref<jni::JMap<jni::JString, jni::JString>> {
      auto __map = jni::JHashMap<jni::JString, jni::JString>::create(httpHeaders.value().size());
      for (const auto& __entry : httpHeaders.value()) {
        __map->put(jni::make_jstring(__entry.first), jni::make_jstring(__entry.second));
      }
      return __map;
    }() : nullptr);
    return [&]() {
      auto __promise = Promise<std::string>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
        __promise->resolve(__result->toStdString());
      });
      __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<std::string>> JHybridSoundSpec::stopPlayer() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("stopPlayer");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<std::string>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
        __promise->resolve(__result->toStdString());
      });
      __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<std::string>> JHybridSoundSpec::pausePlayer() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("pausePlayer");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<std::string>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
        __promise->resolve(__result->toStdString());
      });
      __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<std::string>> JHybridSoundSpec::resumePlayer() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>()>("resumePlayer");
    auto __result = method(_javaPart);
    return [&]() {
      auto __promise = Promise<std::string>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
        __promise->resolve(__result->toStdString());
      });
      __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<std::string>> JHybridSoundSpec::seekToPlayer(double time) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(double /* time */)>("seekToPlayer");
    auto __result = method(_javaPart, time);
    return [&]() {
      auto __promise = Promise<std::string>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
        __promise->resolve(__result->toStdString());
      });
      __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<std::string>> JHybridSoundSpec::setVolume(double volume) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(double /* volume */)>("setVolume");
    auto __result = method(_javaPart, volume);
    return [&]() {
      auto __promise = Promise<std::string>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
        __promise->resolve(__result->toStdString());
      });
      __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<std::string>> JHybridSoundSpec::setPlaybackSpeed(double playbackSpeed) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<JPromise::javaobject>(double /* playbackSpeed */)>("setPlaybackSpeed");
    auto __result = method(_javaPart, playbackSpeed);
    return [&]() {
      auto __promise = Promise<std::string>::create();
      __result->cthis()->addOnResolvedListener([=](const jni::alias_ref<jni::JObject>& __boxedResult) {
        auto __result = jni::static_ref_cast<jni::JString>(__boxedResult);
        __promise->resolve(__result->toStdString());
      });
      __result->cthis()->addOnRejectedListener([=](const jni::alias_ref<jni::JThrowable>& __throwable) {
        jni::JniException __jniError(__throwable);
        __promise->reject(std::make_exception_ptr(__jniError));
      });
      return __promise;
    }();
  }
  void JHybridSoundSpec::setSubscriptionDuration(double sec) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(double /* sec */)>("setSubscriptionDuration");
    method(_javaPart, sec);
  }
  void JHybridSoundSpec::addRecordBackListener(const std::function<void(const RecordBackType& /* recordingMeta */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_RecordBackType::javaobject> /* callback */)>("addRecordBackListener_cxx");
    method(_javaPart, JFunc_void_RecordBackType_cxx::fromCpp(callback));
  }
  void JHybridSoundSpec::removeRecordBackListener() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("removeRecordBackListener");
    method(_javaPart);
  }
  void JHybridSoundSpec::addPlayBackListener(const std::function<void(const PlayBackType& /* playbackMeta */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_PlayBackType::javaobject> /* callback */)>("addPlayBackListener_cxx");
    method(_javaPart, JFunc_void_PlayBackType_cxx::fromCpp(callback));
  }
  void JHybridSoundSpec::removePlayBackListener() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("removePlayBackListener");
    method(_javaPart);
  }
  void JHybridSoundSpec::addPlaybackEndListener(const std::function<void(const PlaybackEndType& /* playbackEndMeta */)>& callback) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void(jni::alias_ref<JFunc_void_PlaybackEndType::javaobject> /* callback */)>("addPlaybackEndListener_cxx");
    method(_javaPart, JFunc_void_PlaybackEndType_cxx::fromCpp(callback));
  }
  void JHybridSoundSpec::removePlaybackEndListener() {
    static const auto method = _javaPart->javaClassStatic()->getMethod<void()>("removePlaybackEndListener");
    method(_javaPart);
  }
  std::string JHybridSoundSpec::mmss(double secs) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>(double /* secs */)>("mmss");
    auto __result = method(_javaPart, secs);
    return __result->toStdString();
  }
  std::string JHybridSoundSpec::mmssss(double milisecs) {
    static const auto method = _javaPart->javaClassStatic()->getMethod<jni::local_ref<jni::JString>(double /* milisecs */)>("mmssss");
    auto __result = method(_javaPart, milisecs);
    return __result->toStdString();
  }

} // namespace margelo::nitro::sound
