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

#pragma once

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

#include "JLivePlaybackParams.hpp"
#include "JResolution.hpp"
#include "LivePlaybackParams.hpp"
#include "Resolution.hpp"
#include <optional>

namespace margelo::nitro::video {

  using namespace facebook;

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

  public:
    /**
     * Convert this Java/Kotlin-based struct to the C++ struct BufferConfig by copying all values to C++.
     */
    [[maybe_unused]]
    [[nodiscard]]
    BufferConfig toCpp() const {
      static const auto clazz = javaClassStatic();
      static const auto fieldLivePlayback = clazz->getField<JLivePlaybackParams>("livePlayback");
      jni::local_ref<JLivePlaybackParams> livePlayback = this->getFieldValue(fieldLivePlayback);
      static const auto fieldMinBufferMs = clazz->getField<jni::JDouble>("minBufferMs");
      jni::local_ref<jni::JDouble> minBufferMs = this->getFieldValue(fieldMinBufferMs);
      static const auto fieldMaxBufferMs = clazz->getField<jni::JDouble>("maxBufferMs");
      jni::local_ref<jni::JDouble> maxBufferMs = this->getFieldValue(fieldMaxBufferMs);
      static const auto fieldBufferForPlaybackMs = clazz->getField<jni::JDouble>("bufferForPlaybackMs");
      jni::local_ref<jni::JDouble> bufferForPlaybackMs = this->getFieldValue(fieldBufferForPlaybackMs);
      static const auto fieldBufferForPlaybackAfterRebufferMs = clazz->getField<jni::JDouble>("bufferForPlaybackAfterRebufferMs");
      jni::local_ref<jni::JDouble> bufferForPlaybackAfterRebufferMs = this->getFieldValue(fieldBufferForPlaybackAfterRebufferMs);
      static const auto fieldBackBufferDurationMs = clazz->getField<jni::JDouble>("backBufferDurationMs");
      jni::local_ref<jni::JDouble> backBufferDurationMs = this->getFieldValue(fieldBackBufferDurationMs);
      static const auto fieldPreferredForwardBufferDurationMs = clazz->getField<jni::JDouble>("preferredForwardBufferDurationMs");
      jni::local_ref<jni::JDouble> preferredForwardBufferDurationMs = this->getFieldValue(fieldPreferredForwardBufferDurationMs);
      static const auto fieldPreferredPeakBitRate = clazz->getField<jni::JDouble>("preferredPeakBitRate");
      jni::local_ref<jni::JDouble> preferredPeakBitRate = this->getFieldValue(fieldPreferredPeakBitRate);
      static const auto fieldPreferredMaximumResolution = clazz->getField<JResolution>("preferredMaximumResolution");
      jni::local_ref<JResolution> preferredMaximumResolution = this->getFieldValue(fieldPreferredMaximumResolution);
      static const auto fieldPreferredPeakBitRateForExpensiveNetworks = clazz->getField<jni::JDouble>("preferredPeakBitRateForExpensiveNetworks");
      jni::local_ref<jni::JDouble> preferredPeakBitRateForExpensiveNetworks = this->getFieldValue(fieldPreferredPeakBitRateForExpensiveNetworks);
      static const auto fieldPreferredMaximumResolutionForExpensiveNetworks = clazz->getField<JResolution>("preferredMaximumResolutionForExpensiveNetworks");
      jni::local_ref<JResolution> preferredMaximumResolutionForExpensiveNetworks = this->getFieldValue(fieldPreferredMaximumResolutionForExpensiveNetworks);
      return BufferConfig(
        livePlayback != nullptr ? std::make_optional(livePlayback->toCpp()) : std::nullopt,
        minBufferMs != nullptr ? std::make_optional(minBufferMs->value()) : std::nullopt,
        maxBufferMs != nullptr ? std::make_optional(maxBufferMs->value()) : std::nullopt,
        bufferForPlaybackMs != nullptr ? std::make_optional(bufferForPlaybackMs->value()) : std::nullopt,
        bufferForPlaybackAfterRebufferMs != nullptr ? std::make_optional(bufferForPlaybackAfterRebufferMs->value()) : std::nullopt,
        backBufferDurationMs != nullptr ? std::make_optional(backBufferDurationMs->value()) : std::nullopt,
        preferredForwardBufferDurationMs != nullptr ? std::make_optional(preferredForwardBufferDurationMs->value()) : std::nullopt,
        preferredPeakBitRate != nullptr ? std::make_optional(preferredPeakBitRate->value()) : std::nullopt,
        preferredMaximumResolution != nullptr ? std::make_optional(preferredMaximumResolution->toCpp()) : std::nullopt,
        preferredPeakBitRateForExpensiveNetworks != nullptr ? std::make_optional(preferredPeakBitRateForExpensiveNetworks->value()) : std::nullopt,
        preferredMaximumResolutionForExpensiveNetworks != nullptr ? std::make_optional(preferredMaximumResolutionForExpensiveNetworks->toCpp()) : 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<JBufferConfig::javaobject> fromCpp(const BufferConfig& value) {
      return newInstance(
        value.livePlayback.has_value() ? JLivePlaybackParams::fromCpp(value.livePlayback.value()) : nullptr,
        value.minBufferMs.has_value() ? jni::JDouble::valueOf(value.minBufferMs.value()) : nullptr,
        value.maxBufferMs.has_value() ? jni::JDouble::valueOf(value.maxBufferMs.value()) : nullptr,
        value.bufferForPlaybackMs.has_value() ? jni::JDouble::valueOf(value.bufferForPlaybackMs.value()) : nullptr,
        value.bufferForPlaybackAfterRebufferMs.has_value() ? jni::JDouble::valueOf(value.bufferForPlaybackAfterRebufferMs.value()) : nullptr,
        value.backBufferDurationMs.has_value() ? jni::JDouble::valueOf(value.backBufferDurationMs.value()) : nullptr,
        value.preferredForwardBufferDurationMs.has_value() ? jni::JDouble::valueOf(value.preferredForwardBufferDurationMs.value()) : nullptr,
        value.preferredPeakBitRate.has_value() ? jni::JDouble::valueOf(value.preferredPeakBitRate.value()) : nullptr,
        value.preferredMaximumResolution.has_value() ? JResolution::fromCpp(value.preferredMaximumResolution.value()) : nullptr,
        value.preferredPeakBitRateForExpensiveNetworks.has_value() ? jni::JDouble::valueOf(value.preferredPeakBitRateForExpensiveNetworks.value()) : nullptr,
        value.preferredMaximumResolutionForExpensiveNetworks.has_value() ? JResolution::fromCpp(value.preferredMaximumResolutionForExpensiveNetworks.value()) : nullptr
      );
    }
  };

} // namespace margelo::nitro::video
