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

#pragma once

#include <fbjni/fbjni.h>
#include "AudioSet.hpp"

#include "AVEncoderAudioQualityIOSType.hpp"
#include "AVEncodingOption.hpp"
#include "AVLinearPCMBitDepthKeyIOSType.hpp"
#include "AVModeIOSOption.hpp"
#include "AudioEncoderAndroidType.hpp"
#include "AudioQualityType.hpp"
#include "AudioSourceAndroidType.hpp"
#include "JAVEncoderAudioQualityIOSType.hpp"
#include "JAVEncodingOption.hpp"
#include "JAVLinearPCMBitDepthKeyIOSType.hpp"
#include "JAVModeIOSOption.hpp"
#include "JAudioEncoderAndroidType.hpp"
#include "JAudioQualityType.hpp"
#include "JAudioSourceAndroidType.hpp"
#include "JOutputFormatAndroidType.hpp"
#include "OutputFormatAndroidType.hpp"
#include <optional>

namespace margelo::nitro::sound {

  using namespace facebook;

  /**
   * The C++ JNI bridge between the C++ struct "AudioSet" and the the Kotlin data class "AudioSet".
   */
  struct JAudioSet final: public jni::JavaClass<JAudioSet> {
  public:
    static constexpr auto kJavaDescriptor = "Lcom/margelo/nitro/sound/AudioSet;";

  public:
    /**
     * Convert this Java/Kotlin-based struct to the C++ struct AudioSet by copying all values to C++.
     */
    [[maybe_unused]]
    [[nodiscard]]
    AudioSet toCpp() const {
      static const auto clazz = javaClassStatic();
      static const auto fieldAVEncoderAudioQualityKeyIOS = clazz->getField<JAVEncoderAudioQualityIOSType>("AVEncoderAudioQualityKeyIOS");
      jni::local_ref<JAVEncoderAudioQualityIOSType> AVEncoderAudioQualityKeyIOS = this->getFieldValue(fieldAVEncoderAudioQualityKeyIOS);
      static const auto fieldAVModeIOS = clazz->getField<JAVModeIOSOption>("AVModeIOS");
      jni::local_ref<JAVModeIOSOption> AVModeIOS = this->getFieldValue(fieldAVModeIOS);
      static const auto fieldAVEncodingOptionIOS = clazz->getField<JAVEncodingOption>("AVEncodingOptionIOS");
      jni::local_ref<JAVEncodingOption> AVEncodingOptionIOS = this->getFieldValue(fieldAVEncodingOptionIOS);
      static const auto fieldAVFormatIDKeyIOS = clazz->getField<JAVEncodingOption>("AVFormatIDKeyIOS");
      jni::local_ref<JAVEncodingOption> AVFormatIDKeyIOS = this->getFieldValue(fieldAVFormatIDKeyIOS);
      static const auto fieldAVNumberOfChannelsKeyIOS = clazz->getField<jni::JDouble>("AVNumberOfChannelsKeyIOS");
      jni::local_ref<jni::JDouble> AVNumberOfChannelsKeyIOS = this->getFieldValue(fieldAVNumberOfChannelsKeyIOS);
      static const auto fieldAVLinearPCMBitDepthKeyIOS = clazz->getField<JAVLinearPCMBitDepthKeyIOSType>("AVLinearPCMBitDepthKeyIOS");
      jni::local_ref<JAVLinearPCMBitDepthKeyIOSType> AVLinearPCMBitDepthKeyIOS = this->getFieldValue(fieldAVLinearPCMBitDepthKeyIOS);
      static const auto fieldAVLinearPCMIsBigEndianKeyIOS = clazz->getField<jni::JBoolean>("AVLinearPCMIsBigEndianKeyIOS");
      jni::local_ref<jni::JBoolean> AVLinearPCMIsBigEndianKeyIOS = this->getFieldValue(fieldAVLinearPCMIsBigEndianKeyIOS);
      static const auto fieldAVLinearPCMIsFloatKeyIOS = clazz->getField<jni::JBoolean>("AVLinearPCMIsFloatKeyIOS");
      jni::local_ref<jni::JBoolean> AVLinearPCMIsFloatKeyIOS = this->getFieldValue(fieldAVLinearPCMIsFloatKeyIOS);
      static const auto fieldAVLinearPCMIsNonInterleavedIOS = clazz->getField<jni::JBoolean>("AVLinearPCMIsNonInterleavedIOS");
      jni::local_ref<jni::JBoolean> AVLinearPCMIsNonInterleavedIOS = this->getFieldValue(fieldAVLinearPCMIsNonInterleavedIOS);
      static const auto fieldAVSampleRateKeyIOS = clazz->getField<jni::JDouble>("AVSampleRateKeyIOS");
      jni::local_ref<jni::JDouble> AVSampleRateKeyIOS = this->getFieldValue(fieldAVSampleRateKeyIOS);
      static const auto fieldAudioSourceAndroid = clazz->getField<JAudioSourceAndroidType>("AudioSourceAndroid");
      jni::local_ref<JAudioSourceAndroidType> AudioSourceAndroid = this->getFieldValue(fieldAudioSourceAndroid);
      static const auto fieldOutputFormatAndroid = clazz->getField<JOutputFormatAndroidType>("OutputFormatAndroid");
      jni::local_ref<JOutputFormatAndroidType> OutputFormatAndroid = this->getFieldValue(fieldOutputFormatAndroid);
      static const auto fieldAudioEncoderAndroid = clazz->getField<JAudioEncoderAndroidType>("AudioEncoderAndroid");
      jni::local_ref<JAudioEncoderAndroidType> AudioEncoderAndroid = this->getFieldValue(fieldAudioEncoderAndroid);
      static const auto fieldAudioQuality = clazz->getField<JAudioQualityType>("AudioQuality");
      jni::local_ref<JAudioQualityType> AudioQuality = this->getFieldValue(fieldAudioQuality);
      static const auto fieldAudioChannels = clazz->getField<jni::JDouble>("AudioChannels");
      jni::local_ref<jni::JDouble> AudioChannels = this->getFieldValue(fieldAudioChannels);
      static const auto fieldAudioSamplingRate = clazz->getField<jni::JDouble>("AudioSamplingRate");
      jni::local_ref<jni::JDouble> AudioSamplingRate = this->getFieldValue(fieldAudioSamplingRate);
      static const auto fieldAudioEncodingBitRate = clazz->getField<jni::JDouble>("AudioEncodingBitRate");
      jni::local_ref<jni::JDouble> AudioEncodingBitRate = this->getFieldValue(fieldAudioEncodingBitRate);
      static const auto fieldIncludeBase64 = clazz->getField<jni::JBoolean>("IncludeBase64");
      jni::local_ref<jni::JBoolean> IncludeBase64 = this->getFieldValue(fieldIncludeBase64);
      return AudioSet(
        AVEncoderAudioQualityKeyIOS != nullptr ? std::make_optional(AVEncoderAudioQualityKeyIOS->toCpp()) : std::nullopt,
        AVModeIOS != nullptr ? std::make_optional(AVModeIOS->toCpp()) : std::nullopt,
        AVEncodingOptionIOS != nullptr ? std::make_optional(AVEncodingOptionIOS->toCpp()) : std::nullopt,
        AVFormatIDKeyIOS != nullptr ? std::make_optional(AVFormatIDKeyIOS->toCpp()) : std::nullopt,
        AVNumberOfChannelsKeyIOS != nullptr ? std::make_optional(AVNumberOfChannelsKeyIOS->value()) : std::nullopt,
        AVLinearPCMBitDepthKeyIOS != nullptr ? std::make_optional(AVLinearPCMBitDepthKeyIOS->toCpp()) : std::nullopt,
        AVLinearPCMIsBigEndianKeyIOS != nullptr ? std::make_optional(static_cast<bool>(AVLinearPCMIsBigEndianKeyIOS->value())) : std::nullopt,
        AVLinearPCMIsFloatKeyIOS != nullptr ? std::make_optional(static_cast<bool>(AVLinearPCMIsFloatKeyIOS->value())) : std::nullopt,
        AVLinearPCMIsNonInterleavedIOS != nullptr ? std::make_optional(static_cast<bool>(AVLinearPCMIsNonInterleavedIOS->value())) : std::nullopt,
        AVSampleRateKeyIOS != nullptr ? std::make_optional(AVSampleRateKeyIOS->value()) : std::nullopt,
        AudioSourceAndroid != nullptr ? std::make_optional(AudioSourceAndroid->toCpp()) : std::nullopt,
        OutputFormatAndroid != nullptr ? std::make_optional(OutputFormatAndroid->toCpp()) : std::nullopt,
        AudioEncoderAndroid != nullptr ? std::make_optional(AudioEncoderAndroid->toCpp()) : std::nullopt,
        AudioQuality != nullptr ? std::make_optional(AudioQuality->toCpp()) : std::nullopt,
        AudioChannels != nullptr ? std::make_optional(AudioChannels->value()) : std::nullopt,
        AudioSamplingRate != nullptr ? std::make_optional(AudioSamplingRate->value()) : std::nullopt,
        AudioEncodingBitRate != nullptr ? std::make_optional(AudioEncodingBitRate->value()) : std::nullopt,
        IncludeBase64 != nullptr ? std::make_optional(static_cast<bool>(IncludeBase64->value())) : std::nullopt
      );
    }

  public:
    /**
     * Create a Java/Kotlin-based struct by copying all values from the given C++ struct to Java.
     */
    [[maybe_unused]]
    static jni::local_ref<JAudioSet::javaobject> fromCpp(const AudioSet& value) {
      using JSignature = JAudioSet(jni::alias_ref<JAVEncoderAudioQualityIOSType>, jni::alias_ref<JAVModeIOSOption>, jni::alias_ref<JAVEncodingOption>, jni::alias_ref<JAVEncodingOption>, jni::alias_ref<jni::JDouble>, jni::alias_ref<JAVLinearPCMBitDepthKeyIOSType>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JDouble>, jni::alias_ref<JAudioSourceAndroidType>, jni::alias_ref<JOutputFormatAndroidType>, jni::alias_ref<JAudioEncoderAndroidType>, jni::alias_ref<JAudioQualityType>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JBoolean>);
      static const auto clazz = javaClassStatic();
      static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
      return create(
        clazz,
        value.AVEncoderAudioQualityKeyIOS.has_value() ? JAVEncoderAudioQualityIOSType::fromCpp(value.AVEncoderAudioQualityKeyIOS.value()) : nullptr,
        value.AVModeIOS.has_value() ? JAVModeIOSOption::fromCpp(value.AVModeIOS.value()) : nullptr,
        value.AVEncodingOptionIOS.has_value() ? JAVEncodingOption::fromCpp(value.AVEncodingOptionIOS.value()) : nullptr,
        value.AVFormatIDKeyIOS.has_value() ? JAVEncodingOption::fromCpp(value.AVFormatIDKeyIOS.value()) : nullptr,
        value.AVNumberOfChannelsKeyIOS.has_value() ? jni::JDouble::valueOf(value.AVNumberOfChannelsKeyIOS.value()) : nullptr,
        value.AVLinearPCMBitDepthKeyIOS.has_value() ? JAVLinearPCMBitDepthKeyIOSType::fromCpp(value.AVLinearPCMBitDepthKeyIOS.value()) : nullptr,
        value.AVLinearPCMIsBigEndianKeyIOS.has_value() ? jni::JBoolean::valueOf(value.AVLinearPCMIsBigEndianKeyIOS.value()) : nullptr,
        value.AVLinearPCMIsFloatKeyIOS.has_value() ? jni::JBoolean::valueOf(value.AVLinearPCMIsFloatKeyIOS.value()) : nullptr,
        value.AVLinearPCMIsNonInterleavedIOS.has_value() ? jni::JBoolean::valueOf(value.AVLinearPCMIsNonInterleavedIOS.value()) : nullptr,
        value.AVSampleRateKeyIOS.has_value() ? jni::JDouble::valueOf(value.AVSampleRateKeyIOS.value()) : nullptr,
        value.AudioSourceAndroid.has_value() ? JAudioSourceAndroidType::fromCpp(value.AudioSourceAndroid.value()) : nullptr,
        value.OutputFormatAndroid.has_value() ? JOutputFormatAndroidType::fromCpp(value.OutputFormatAndroid.value()) : nullptr,
        value.AudioEncoderAndroid.has_value() ? JAudioEncoderAndroidType::fromCpp(value.AudioEncoderAndroid.value()) : nullptr,
        value.AudioQuality.has_value() ? JAudioQualityType::fromCpp(value.AudioQuality.value()) : nullptr,
        value.AudioChannels.has_value() ? jni::JDouble::valueOf(value.AudioChannels.value()) : nullptr,
        value.AudioSamplingRate.has_value() ? jni::JDouble::valueOf(value.AudioSamplingRate.value()) : nullptr,
        value.AudioEncodingBitRate.has_value() ? jni::JDouble::valueOf(value.AudioEncodingBitRate.value()) : nullptr,
        value.IncludeBase64.has_value() ? jni::JBoolean::valueOf(value.IncludeBase64.value()) : nullptr
      );
    }
  };

} // namespace margelo::nitro::sound
