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

#pragma once

#include "HybridNetSocketDriverSpec.hpp"

// Forward declaration of `HybridNetSocketDriverSpec_cxx` to properly resolve imports.
namespace RustCNet { class HybridNetSocketDriverSpec_cxx; }

// Forward declaration of `ArrayBufferHolder` to properly resolve imports.
namespace NitroModules { class ArrayBufferHolder; }

#include <NitroModules/ArrayBuffer.hpp>
#include <functional>
#include <NitroModules/ArrayBufferHolder.hpp>
#include <string>
#include <optional>

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

namespace margelo::nitro::net {

  /**
   * The C++ part of HybridNetSocketDriverSpec_cxx.swift.
   *
   * HybridNetSocketDriverSpecSwift (C++) accesses HybridNetSocketDriverSpec_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, HybridNetSocketDriverSpec_cxx can directly inherit from the C++ class HybridNetSocketDriverSpec
   * to simplify the whole structure and memory management.
   */
  class HybridNetSocketDriverSpecSwift: public virtual HybridNetSocketDriverSpec {
  public:
    // Constructor from a Swift instance
    explicit HybridNetSocketDriverSpecSwift(const RustCNet::HybridNetSocketDriverSpec_cxx& swiftPart):
      HybridObject(HybridNetSocketDriverSpec::TAG),
      _swiftPart(swiftPart) { }

  public:
    // Get the Swift part
    inline RustCNet::HybridNetSocketDriverSpec_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<HybridNetSocketDriverSpecSwift>(other)) {
        return _swiftPart.equals(otherCast->_swiftPart);
      }
      return false;
    }
    void dispose() noexcept override {
      _swiftPart.dispose();
    }
    std::string toString() override {
      return _swiftPart.toString();
    }

  public:
    // Properties
    inline double getId() noexcept override {
      return _swiftPart.getId();
    }
    inline std::function<void(double /* event */, const std::shared_ptr<ArrayBuffer>& /* data */)> getOnEvent() noexcept override {
      auto __result = _swiftPart.getOnEvent();
      return __result;
    }
    inline void setOnEvent(const std::function<void(double /* event */, const std::shared_ptr<ArrayBuffer>& /* data */)>& onEvent) noexcept override {
      _swiftPart.setOnEvent(onEvent);
    }

  public:
    // Methods
    inline void connect(const std::string& host, double port) override {
      auto __result = _swiftPart.connect(host, std::forward<decltype(port)>(port));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void connectTLS(const std::string& host, double port, const std::optional<std::string>& serverName, std::optional<bool> rejectUnauthorized) override {
      auto __result = _swiftPart.connectTLS(host, std::forward<decltype(port)>(port), serverName, rejectUnauthorized);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void connectTLSWithContext(const std::string& host, double port, const std::optional<std::string>& serverName, std::optional<bool> rejectUnauthorized, std::optional<double> secureContextId) override {
      auto __result = _swiftPart.connectTLSWithContext(host, std::forward<decltype(port)>(port), serverName, rejectUnauthorized, secureContextId);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline std::optional<std::string> getAuthorizationError() override {
      auto __result = _swiftPart.getAuthorizationError();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::optional<std::string> getProtocol() override {
      auto __result = _swiftPart.getProtocol();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::optional<std::string> getCipher() override {
      auto __result = _swiftPart.getCipher();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::optional<std::string> getALPN() override {
      auto __result = _swiftPart.getALPN();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::optional<std::string> getPeerCertificateJSON() override {
      auto __result = _swiftPart.getPeerCertificateJSON();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::optional<std::string> getEphemeralKeyInfo() override {
      auto __result = _swiftPart.getEphemeralKeyInfo();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::optional<std::string> getSharedSigalgs() override {
      auto __result = _swiftPart.getSharedSigalgs();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline bool isSessionReused() override {
      auto __result = _swiftPart.isSessionReused();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::optional<std::shared_ptr<ArrayBuffer>> getSession() override {
      auto __result = _swiftPart.getSession();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline void setSession(const std::shared_ptr<ArrayBuffer>& session) override {
      auto __result = _swiftPart.setSession(ArrayBufferHolder(session));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void connectUnix(const std::string& path) override {
      auto __result = _swiftPart.connectUnix(path);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void connectUnixTLS(const std::string& path, const std::optional<std::string>& serverName, std::optional<bool> rejectUnauthorized) override {
      auto __result = _swiftPart.connectUnixTLS(path, serverName, rejectUnauthorized);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void connectUnixTLSWithContext(const std::string& path, const std::optional<std::string>& serverName, std::optional<bool> rejectUnauthorized, std::optional<double> secureContextId) override {
      auto __result = _swiftPart.connectUnixTLSWithContext(path, serverName, rejectUnauthorized, secureContextId);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void write(const std::shared_ptr<ArrayBuffer>& data) override {
      auto __result = _swiftPart.write(ArrayBufferHolder(data));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void pause() override {
      auto __result = _swiftPart.pause();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void resume() override {
      auto __result = _swiftPart.resume();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void shutdown() override {
      auto __result = _swiftPart.shutdown();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setTimeout(double timeout) override {
      auto __result = _swiftPart.setTimeout(std::forward<decltype(timeout)>(timeout));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void destroy() override {
      auto __result = _swiftPart.destroy();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void resetAndDestroy() override {
      auto __result = _swiftPart.resetAndDestroy();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void enableKeylog() override {
      auto __result = _swiftPart.enableKeylog();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void enableTrace() override {
      auto __result = _swiftPart.enableTrace();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline std::optional<std::shared_ptr<ArrayBuffer>> exportKeyingMaterial(double length, const std::string& label, const std::optional<std::shared_ptr<ArrayBuffer>>& context) override {
      auto __result = _swiftPart.exportKeyingMaterial(std::forward<decltype(length)>(length), label, context);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline void setNoDelay(bool enable) override {
      auto __result = _swiftPart.setNoDelay(std::forward<decltype(enable)>(enable));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setKeepAlive(bool enable, double delay) override {
      auto __result = _swiftPart.setKeepAlive(std::forward<decltype(enable)>(enable), std::forward<decltype(delay)>(delay));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline std::string getLocalAddress() override {
      auto __result = _swiftPart.getLocalAddress();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::string getRemoteAddress() override {
      auto __result = _swiftPart.getRemoteAddress();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }

  private:
    RustCNet::HybridNetSocketDriverSpec_cxx _swiftPart;
  };

} // namespace margelo::nitro::net
