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

#pragma once

#include "HybridMailMailboxSpec.hpp"

// Forward declaration of `HybridMailMailboxSpec_cxx` to properly resolve imports.
namespace MailEngine { class HybridMailMailboxSpec_cxx; }

// Forward declaration of `MailHeaderStruct` to properly resolve imports.
namespace margelo::nitro::mailengine { struct MailHeaderStruct; }
// Forward declaration of `MailAddressStruct` to properly resolve imports.
namespace margelo::nitro::mailengine { struct MailAddressStruct; }
// Forward declaration of `MailFetchHeadersOptions` to properly resolve imports.
namespace margelo::nitro::mailengine { struct MailFetchHeadersOptions; }
// Forward declaration of `MailMessageStruct` to properly resolve imports.
namespace margelo::nitro::mailengine { struct MailMessageStruct; }
// Forward declaration of `MailAttachmentStruct` to properly resolve imports.
namespace margelo::nitro::mailengine { struct MailAttachmentStruct; }
// Forward declaration of `ArrayBufferHolder` to properly resolve imports.
namespace NitroModules { class ArrayBufferHolder; }
// Forward declaration of `MailFetchMessageOptions` to properly resolve imports.
namespace margelo::nitro::mailengine { struct MailFetchMessageOptions; }
// Forward declaration of `MailSearchCriteria` to properly resolve imports.
namespace margelo::nitro::mailengine { struct MailSearchCriteria; }
// Forward declaration of `MailNewMailEvent` to properly resolve imports.
namespace margelo::nitro::mailengine { struct MailNewMailEvent; }
// Forward declaration of `MailErrorStruct` to properly resolve imports.
namespace margelo::nitro::mailengine { struct MailErrorStruct; }

#include <string>
#include "MailHeaderStruct.hpp"
#include <vector>
#include <NitroModules/Promise.hpp>
#include <optional>
#include "MailAddressStruct.hpp"
#include "MailFetchHeadersOptions.hpp"
#include "MailMessageStruct.hpp"
#include "MailAttachmentStruct.hpp"
#include <NitroModules/ArrayBuffer.hpp>
#include <NitroModules/ArrayBufferHolder.hpp>
#include "MailFetchMessageOptions.hpp"
#include "MailSearchCriteria.hpp"
#include "MailNewMailEvent.hpp"
#include <functional>
#include "MailErrorStruct.hpp"

#include "MailEngine-Swift-Cxx-Umbrella.hpp"

namespace margelo::nitro::mailengine {

  /**
   * The C++ part of HybridMailMailboxSpec_cxx.swift.
   *
   * HybridMailMailboxSpecSwift (C++) accesses HybridMailMailboxSpec_cxx (Swift), and might
   * contain some additional bridging code for C++ <> Swift interop.
   *
   * Since this obviously introduces an overhead, I hope at some point in
   * the future, HybridMailMailboxSpec_cxx can directly inherit from the C++ class HybridMailMailboxSpec
   * to simplify the whole structure and memory management.
   */
  class HybridMailMailboxSpecSwift: public virtual HybridMailMailboxSpec {
  public:
    // Constructor from a Swift instance
    explicit HybridMailMailboxSpecSwift(const MailEngine::HybridMailMailboxSpec_cxx& swiftPart):
      HybridObject(HybridMailMailboxSpec::TAG),
      _swiftPart(swiftPart) { }

  public:
    // Get the Swift part
    inline MailEngine::HybridMailMailboxSpec_cxx& getSwiftPart() noexcept {
      return _swiftPart;
    }

  public:
    inline size_t getExternalMemorySize() noexcept override {
      return _swiftPart.getMemorySize();
    }
    bool equals(const std::shared_ptr<HybridObject>& other) override {
      if (auto otherCast = std::dynamic_pointer_cast<HybridMailMailboxSpecSwift>(other)) {
        return _swiftPart.equals(otherCast->_swiftPart);
      }
      return false;
    }
    void dispose() noexcept override {
      _swiftPart.dispose();
    }
    std::string toString() override {
      return _swiftPart.toString();
    }

  public:
    // Properties
    inline std::string getPath() noexcept override {
      auto __result = _swiftPart.getPath();
      return __result;
    }
    inline double getExists() noexcept override {
      return _swiftPart.getExists();
    }
    inline double getUnseen() noexcept override {
      return _swiftPart.getUnseen();
    }
    inline double getUidNext() noexcept override {
      return _swiftPart.getUidNext();
    }
    inline double getUidValidity() noexcept override {
      return _swiftPart.getUidValidity();
    }

  public:
    // Methods
    inline std::shared_ptr<Promise<std::vector<MailHeaderStruct>>> fetchHeaders(const MailFetchHeadersOptions& options) override {
      auto __result = _swiftPart.fetchHeaders(std::forward<decltype(options)>(options));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<MailMessageStruct>> fetchMessage(double uid, const MailFetchMessageOptions& options) override {
      auto __result = _swiftPart.fetchMessage(std::forward<decltype(uid)>(uid), std::forward<decltype(options)>(options));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::shared_ptr<ArrayBuffer>>> fetchAttachment(double uid, const std::string& partId) override {
      auto __result = _swiftPart.fetchAttachment(std::forward<decltype(uid)>(uid), partId);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::vector<double>>> search(const MailSearchCriteria& criteria) override {
      auto __result = _swiftPart.search(std::forward<decltype(criteria)>(criteria));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> addFlags(const std::vector<double>& uids, const std::vector<std::string>& flags) override {
      auto __result = _swiftPart.addFlags(uids, flags);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> removeFlags(const std::vector<double>& uids, const std::vector<std::string>& flags) override {
      auto __result = _swiftPart.removeFlags(uids, flags);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> markSeen(const std::vector<double>& uids, bool seen) override {
      auto __result = _swiftPart.markSeen(uids, std::forward<decltype(seen)>(seen));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> moveMessages(const std::vector<double>& uids, const std::string& destinationPath) override {
      auto __result = _swiftPart.moveMessages(uids, destinationPath);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> copyMessages(const std::vector<double>& uids, const std::string& destinationPath) override {
      auto __result = _swiftPart.copyMessages(uids, destinationPath);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> deleteMessages(const std::vector<double>& uids, bool expunge) override {
      auto __result = _swiftPart.deleteMessages(uids, std::forward<decltype(expunge)>(expunge));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> startIdle(const std::function<void(const MailNewMailEvent& /* event */)>& onMail, const std::function<void(const MailErrorStruct& /* error */)>& onError) override {
      auto __result = _swiftPart.startIdle(onMail, onError);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> stopIdle() override {
      auto __result = _swiftPart.stopIdle();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> close() override {
      auto __result = _swiftPart.close();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }

  private:
    MailEngine::HybridMailMailboxSpec_cxx _swiftPart;
  };

} // namespace margelo::nitro::mailengine
