///
/// JDfuOptions.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 "DfuOptions.hpp"

#include "DfuFirmwareType.hpp"
#include "JDfuFirmwareType.hpp"
#include <optional>
#include <string>

namespace margelo::nitro::co::zyke::dfu {

  using namespace facebook;

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

  public:
    /**
     * Convert this Java/Kotlin-based struct to the C++ struct DfuOptions by copying all values to C++.
     */
    [[maybe_unused]]
    [[nodiscard]]
    DfuOptions toCpp() const {
      static const auto clazz = javaClassStatic();
      static const auto fieldDeviceId = clazz->getField<jni::JString>("deviceId");
      jni::local_ref<jni::JString> deviceId = this->getFieldValue(fieldDeviceId);
      static const auto fieldFilePath = clazz->getField<jni::JString>("filePath");
      jni::local_ref<jni::JString> filePath = this->getFieldValue(fieldFilePath);
      static const auto fieldFirmwareType = clazz->getField<JDfuFirmwareType>("firmwareType");
      jni::local_ref<JDfuFirmwareType> firmwareType = this->getFieldValue(fieldFirmwareType);
      static const auto fieldPacketReceiptNotificationParameter = clazz->getField<jni::JDouble>("packetReceiptNotificationParameter");
      jni::local_ref<jni::JDouble> packetReceiptNotificationParameter = this->getFieldValue(fieldPacketReceiptNotificationParameter);
      static const auto fieldForceDfu = clazz->getField<jni::JBoolean>("forceDfu");
      jni::local_ref<jni::JBoolean> forceDfu = this->getFieldValue(fieldForceDfu);
      static const auto fieldEnableUnsafeExperimentalButtonlessDfu = clazz->getField<jni::JBoolean>("enableUnsafeExperimentalButtonlessDfu");
      jni::local_ref<jni::JBoolean> enableUnsafeExperimentalButtonlessDfu = this->getFieldValue(fieldEnableUnsafeExperimentalButtonlessDfu);
      static const auto fieldForceScanningForNewAddressInLegacyDfu = clazz->getField<jni::JBoolean>("forceScanningForNewAddressInLegacyDfu");
      jni::local_ref<jni::JBoolean> forceScanningForNewAddressInLegacyDfu = this->getFieldValue(fieldForceScanningForNewAddressInLegacyDfu);
      static const auto fieldNumberOfRetries = clazz->getField<jni::JDouble>("numberOfRetries");
      jni::local_ref<jni::JDouble> numberOfRetries = this->getFieldValue(fieldNumberOfRetries);
      static const auto fieldConnectionTimeout = clazz->getField<jni::JDouble>("connectionTimeout");
      jni::local_ref<jni::JDouble> connectionTimeout = this->getFieldValue(fieldConnectionTimeout);
      static const auto fieldDataObjectPreparationDelay = clazz->getField<jni::JDouble>("dataObjectPreparationDelay");
      jni::local_ref<jni::JDouble> dataObjectPreparationDelay = this->getFieldValue(fieldDataObjectPreparationDelay);
      static const auto fieldAlternativeAdvertisingNameEnabled = clazz->getField<jni::JBoolean>("alternativeAdvertisingNameEnabled");
      jni::local_ref<jni::JBoolean> alternativeAdvertisingNameEnabled = this->getFieldValue(fieldAlternativeAdvertisingNameEnabled);
      static const auto fieldDisableResume = clazz->getField<jni::JBoolean>("disableResume");
      jni::local_ref<jni::JBoolean> disableResume = this->getFieldValue(fieldDisableResume);
      return DfuOptions(
        deviceId->toStdString(),
        filePath->toStdString(),
        firmwareType != nullptr ? std::make_optional(firmwareType->toCpp()) : std::nullopt,
        packetReceiptNotificationParameter != nullptr ? std::make_optional(packetReceiptNotificationParameter->value()) : std::nullopt,
        forceDfu != nullptr ? std::make_optional(static_cast<bool>(forceDfu->value())) : std::nullopt,
        enableUnsafeExperimentalButtonlessDfu != nullptr ? std::make_optional(static_cast<bool>(enableUnsafeExperimentalButtonlessDfu->value())) : std::nullopt,
        forceScanningForNewAddressInLegacyDfu != nullptr ? std::make_optional(static_cast<bool>(forceScanningForNewAddressInLegacyDfu->value())) : std::nullopt,
        numberOfRetries != nullptr ? std::make_optional(numberOfRetries->value()) : std::nullopt,
        connectionTimeout != nullptr ? std::make_optional(connectionTimeout->value()) : std::nullopt,
        dataObjectPreparationDelay != nullptr ? std::make_optional(dataObjectPreparationDelay->value()) : std::nullopt,
        alternativeAdvertisingNameEnabled != nullptr ? std::make_optional(static_cast<bool>(alternativeAdvertisingNameEnabled->value())) : std::nullopt,
        disableResume != nullptr ? std::make_optional(static_cast<bool>(disableResume->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<JDfuOptions::javaobject> fromCpp(const DfuOptions& value) {
      using JSignature = JDfuOptions(jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<JDfuFirmwareType>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JDouble>, jni::alias_ref<jni::JBoolean>, jni::alias_ref<jni::JBoolean>);
      static const auto clazz = javaClassStatic();
      static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
      return create(
        clazz,
        jni::make_jstring(value.deviceId),
        jni::make_jstring(value.filePath),
        value.firmwareType.has_value() ? JDfuFirmwareType::fromCpp(value.firmwareType.value()) : nullptr,
        value.packetReceiptNotificationParameter.has_value() ? jni::JDouble::valueOf(value.packetReceiptNotificationParameter.value()) : nullptr,
        value.forceDfu.has_value() ? jni::JBoolean::valueOf(value.forceDfu.value()) : nullptr,
        value.enableUnsafeExperimentalButtonlessDfu.has_value() ? jni::JBoolean::valueOf(value.enableUnsafeExperimentalButtonlessDfu.value()) : nullptr,
        value.forceScanningForNewAddressInLegacyDfu.has_value() ? jni::JBoolean::valueOf(value.forceScanningForNewAddressInLegacyDfu.value()) : nullptr,
        value.numberOfRetries.has_value() ? jni::JDouble::valueOf(value.numberOfRetries.value()) : nullptr,
        value.connectionTimeout.has_value() ? jni::JDouble::valueOf(value.connectionTimeout.value()) : nullptr,
        value.dataObjectPreparationDelay.has_value() ? jni::JDouble::valueOf(value.dataObjectPreparationDelay.value()) : nullptr,
        value.alternativeAdvertisingNameEnabled.has_value() ? jni::JBoolean::valueOf(value.alternativeAdvertisingNameEnabled.value()) : nullptr,
        value.disableResume.has_value() ? jni::JBoolean::valueOf(value.disableResume.value()) : nullptr
      );
    }
  };

} // namespace margelo::nitro::co::zyke::dfu
