///
/// JMailOutgoingMessage.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 "MailOutgoingMessage.hpp"

#include "JMailAddressStruct.hpp"
#include "JMailOutgoingAttachment.hpp"
#include "MailAddressStruct.hpp"
#include "MailOutgoingAttachment.hpp"
#include <NitroModules/ArrayBuffer.hpp>
#include <NitroModules/JArrayBuffer.hpp>
#include <optional>
#include <string>
#include <unordered_map>
#include <vector>

namespace margelo::nitro::mailengine {

  using namespace facebook;

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

  public:
    /**
     * Convert this Java/Kotlin-based struct to the C++ struct MailOutgoingMessage by copying all values to C++.
     */
    [[maybe_unused]]
    [[nodiscard]]
    MailOutgoingMessage toCpp() const {
      static const auto clazz = javaClassStatic();
      static const auto fieldFrom = clazz->getField<JMailAddressStruct>("from");
      jni::local_ref<JMailAddressStruct> from = this->getFieldValue(fieldFrom);
      static const auto fieldTo = clazz->getField<jni::JArrayClass<JMailAddressStruct>>("to");
      jni::local_ref<jni::JArrayClass<JMailAddressStruct>> to = this->getFieldValue(fieldTo);
      static const auto fieldCc = clazz->getField<jni::JArrayClass<JMailAddressStruct>>("cc");
      jni::local_ref<jni::JArrayClass<JMailAddressStruct>> cc = this->getFieldValue(fieldCc);
      static const auto fieldBcc = clazz->getField<jni::JArrayClass<JMailAddressStruct>>("bcc");
      jni::local_ref<jni::JArrayClass<JMailAddressStruct>> bcc = this->getFieldValue(fieldBcc);
      static const auto fieldReplyTo = clazz->getField<jni::JArrayClass<JMailAddressStruct>>("replyTo");
      jni::local_ref<jni::JArrayClass<JMailAddressStruct>> replyTo = this->getFieldValue(fieldReplyTo);
      static const auto fieldSubject = clazz->getField<jni::JString>("subject");
      jni::local_ref<jni::JString> subject = this->getFieldValue(fieldSubject);
      static const auto fieldText = clazz->getField<jni::JString>("text");
      jni::local_ref<jni::JString> text = this->getFieldValue(fieldText);
      static const auto fieldHtml = clazz->getField<jni::JString>("html");
      jni::local_ref<jni::JString> html = this->getFieldValue(fieldHtml);
      static const auto fieldAttachments = clazz->getField<jni::JArrayClass<JMailOutgoingAttachment>>("attachments");
      jni::local_ref<jni::JArrayClass<JMailOutgoingAttachment>> attachments = this->getFieldValue(fieldAttachments);
      static const auto fieldHeaders = clazz->getField<jni::JMap<jni::JString, jni::JString>>("headers");
      jni::local_ref<jni::JMap<jni::JString, jni::JString>> headers = this->getFieldValue(fieldHeaders);
      static const auto fieldInReplyTo = clazz->getField<jni::JString>("inReplyTo");
      jni::local_ref<jni::JString> inReplyTo = this->getFieldValue(fieldInReplyTo);
      static const auto fieldReferences = clazz->getField<jni::JArrayClass<jni::JString>>("references");
      jni::local_ref<jni::JArrayClass<jni::JString>> references = this->getFieldValue(fieldReferences);
      return MailOutgoingMessage(
        from != nullptr ? std::make_optional(from->toCpp()) : std::nullopt,
        [&](auto&& __input) {
          size_t __size = __input->size();
          std::vector<MailAddressStruct> __vector;
          __vector.reserve(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            auto __element = __input->getElement(__i);
            __vector.push_back(__element->toCpp());
          }
          return __vector;
        }(to),
        cc != nullptr ? std::make_optional([&](auto&& __input) {
          size_t __size = __input->size();
          std::vector<MailAddressStruct> __vector;
          __vector.reserve(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            auto __element = __input->getElement(__i);
            __vector.push_back(__element->toCpp());
          }
          return __vector;
        }(cc)) : std::nullopt,
        bcc != nullptr ? std::make_optional([&](auto&& __input) {
          size_t __size = __input->size();
          std::vector<MailAddressStruct> __vector;
          __vector.reserve(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            auto __element = __input->getElement(__i);
            __vector.push_back(__element->toCpp());
          }
          return __vector;
        }(bcc)) : std::nullopt,
        replyTo != nullptr ? std::make_optional([&](auto&& __input) {
          size_t __size = __input->size();
          std::vector<MailAddressStruct> __vector;
          __vector.reserve(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            auto __element = __input->getElement(__i);
            __vector.push_back(__element->toCpp());
          }
          return __vector;
        }(replyTo)) : std::nullopt,
        subject->toStdString(),
        text != nullptr ? std::make_optional(text->toStdString()) : std::nullopt,
        html != nullptr ? std::make_optional(html->toStdString()) : std::nullopt,
        attachments != nullptr ? std::make_optional([&](auto&& __input) {
          size_t __size = __input->size();
          std::vector<MailOutgoingAttachment> __vector;
          __vector.reserve(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            auto __element = __input->getElement(__i);
            __vector.push_back(__element->toCpp());
          }
          return __vector;
        }(attachments)) : std::nullopt,
        headers != nullptr ? std::make_optional([&]() {
          std::unordered_map<std::string, std::string> __map;
          __map.reserve(headers->size());
          for (const auto& __entry : *headers) {
            __map.emplace(__entry.first->toStdString(), __entry.second->toStdString());
          }
          return __map;
        }()) : std::nullopt,
        inReplyTo != nullptr ? std::make_optional(inReplyTo->toStdString()) : std::nullopt,
        references != nullptr ? std::make_optional([&](auto&& __input) {
          size_t __size = __input->size();
          std::vector<std::string> __vector;
          __vector.reserve(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            auto __element = __input->getElement(__i);
            __vector.push_back(__element->toStdString());
          }
          return __vector;
        }(references)) : 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<JMailOutgoingMessage::javaobject> fromCpp(const MailOutgoingMessage& value) {
      using JSignature = JMailOutgoingMessage(jni::alias_ref<JMailAddressStruct>, jni::alias_ref<jni::JArrayClass<JMailAddressStruct>>, jni::alias_ref<jni::JArrayClass<JMailAddressStruct>>, jni::alias_ref<jni::JArrayClass<JMailAddressStruct>>, jni::alias_ref<jni::JArrayClass<JMailAddressStruct>>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JArrayClass<JMailOutgoingAttachment>>, jni::alias_ref<jni::JMap<jni::JString, jni::JString>>, jni::alias_ref<jni::JString>, jni::alias_ref<jni::JArrayClass<jni::JString>>);
      static const auto clazz = javaClassStatic();
      static const auto create = clazz->getStaticMethod<JSignature>("fromCpp");
      return create(
        clazz,
        value.from.has_value() ? JMailAddressStruct::fromCpp(value.from.value()) : nullptr,
        [&](auto&& __input) {
          size_t __size = __input.size();
          jni::local_ref<jni::JArrayClass<JMailAddressStruct>> __array = jni::JArrayClass<JMailAddressStruct>::newArray(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            const auto& __element = __input[__i];
            auto __elementJni = JMailAddressStruct::fromCpp(__element);
            __array->setElement(__i, *__elementJni);
          }
          return __array;
        }(value.to),
        value.cc.has_value() ? [&](auto&& __input) {
          size_t __size = __input.size();
          jni::local_ref<jni::JArrayClass<JMailAddressStruct>> __array = jni::JArrayClass<JMailAddressStruct>::newArray(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            const auto& __element = __input[__i];
            auto __elementJni = JMailAddressStruct::fromCpp(__element);
            __array->setElement(__i, *__elementJni);
          }
          return __array;
        }(value.cc.value()) : nullptr,
        value.bcc.has_value() ? [&](auto&& __input) {
          size_t __size = __input.size();
          jni::local_ref<jni::JArrayClass<JMailAddressStruct>> __array = jni::JArrayClass<JMailAddressStruct>::newArray(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            const auto& __element = __input[__i];
            auto __elementJni = JMailAddressStruct::fromCpp(__element);
            __array->setElement(__i, *__elementJni);
          }
          return __array;
        }(value.bcc.value()) : nullptr,
        value.replyTo.has_value() ? [&](auto&& __input) {
          size_t __size = __input.size();
          jni::local_ref<jni::JArrayClass<JMailAddressStruct>> __array = jni::JArrayClass<JMailAddressStruct>::newArray(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            const auto& __element = __input[__i];
            auto __elementJni = JMailAddressStruct::fromCpp(__element);
            __array->setElement(__i, *__elementJni);
          }
          return __array;
        }(value.replyTo.value()) : nullptr,
        jni::make_jstring(value.subject),
        value.text.has_value() ? jni::make_jstring(value.text.value()) : nullptr,
        value.html.has_value() ? jni::make_jstring(value.html.value()) : nullptr,
        value.attachments.has_value() ? [&](auto&& __input) {
          size_t __size = __input.size();
          jni::local_ref<jni::JArrayClass<JMailOutgoingAttachment>> __array = jni::JArrayClass<JMailOutgoingAttachment>::newArray(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            const auto& __element = __input[__i];
            auto __elementJni = JMailOutgoingAttachment::fromCpp(__element);
            __array->setElement(__i, *__elementJni);
          }
          return __array;
        }(value.attachments.value()) : nullptr,
        value.headers.has_value() ? [&]() -> jni::local_ref<jni::JMap<jni::JString, jni::JString>> {
          auto __map = jni::JHashMap<jni::JString, jni::JString>::create(value.headers.value().size());
          for (const auto& __entry : value.headers.value()) {
            __map->put(jni::make_jstring(__entry.first), jni::make_jstring(__entry.second));
          }
          return __map;
        }() : nullptr,
        value.inReplyTo.has_value() ? jni::make_jstring(value.inReplyTo.value()) : nullptr,
        value.references.has_value() ? [&](auto&& __input) {
          size_t __size = __input.size();
          jni::local_ref<jni::JArrayClass<jni::JString>> __array = jni::JArrayClass<jni::JString>::newArray(__size);
          for (size_t __i = 0; __i < __size; __i++) {
            const auto& __element = __input[__i];
            auto __elementJni = jni::make_jstring(__element);
            __array->setElement(__i, *__elementJni);
          }
          return __array;
        }(value.references.value()) : nullptr
      );
    }
  };

} // namespace margelo::nitro::mailengine
