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

#pragma once

#include "HybridSoundSpec.hpp"

// Forward declaration of `HybridSoundSpec_cxx` to properly resolve imports.
namespace NitroSound { class HybridSoundSpec_cxx; }

// Forward declaration of `AudioSet` to properly resolve imports.
namespace margelo::nitro::sound { struct AudioSet; }
// Forward declaration of `AVEncoderAudioQualityIOSType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVEncoderAudioQualityIOSType; }
// Forward declaration of `AVModeIOSOption` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVModeIOSOption; }
// Forward declaration of `AVEncodingOption` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVEncodingOption; }
// Forward declaration of `AVLinearPCMBitDepthKeyIOSType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AVLinearPCMBitDepthKeyIOSType; }
// Forward declaration of `AudioSourceAndroidType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AudioSourceAndroidType; }
// Forward declaration of `OutputFormatAndroidType` to properly resolve imports.
namespace margelo::nitro::sound { enum class OutputFormatAndroidType; }
// Forward declaration of `AudioEncoderAndroidType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AudioEncoderAndroidType; }
// Forward declaration of `AudioQualityType` to properly resolve imports.
namespace margelo::nitro::sound { enum class AudioQualityType; }
// Forward declaration of `RecordBackType` to properly resolve imports.
namespace margelo::nitro::sound { struct RecordBackType; }
// Forward declaration of `PlayBackType` to properly resolve imports.
namespace margelo::nitro::sound { struct PlayBackType; }
// Forward declaration of `PlaybackEndType` to properly resolve imports.
namespace margelo::nitro::sound { struct PlaybackEndType; }

#include <string>
#include <NitroModules/Promise.hpp>
#include <optional>
#include "AudioSet.hpp"
#include "AVEncoderAudioQualityIOSType.hpp"
#include "AVModeIOSOption.hpp"
#include "AVEncodingOption.hpp"
#include "AVLinearPCMBitDepthKeyIOSType.hpp"
#include "AudioSourceAndroidType.hpp"
#include "OutputFormatAndroidType.hpp"
#include "AudioEncoderAndroidType.hpp"
#include "AudioQualityType.hpp"
#include <unordered_map>
#include "RecordBackType.hpp"
#include <functional>
#include "PlayBackType.hpp"
#include "PlaybackEndType.hpp"

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

namespace margelo::nitro::sound {

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

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

  public:
    // Properties
    

  public:
    // Methods
    inline std::shared_ptr<Promise<std::string>> startRecorder(const std::optional<std::string>& uri, const std::optional<AudioSet>& audioSets, std::optional<bool> meteringEnabled) override {
      auto __result = _swiftPart.startRecorder(uri, audioSets, meteringEnabled);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::string>> pauseRecorder() override {
      auto __result = _swiftPart.pauseRecorder();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::string>> resumeRecorder() override {
      auto __result = _swiftPart.resumeRecorder();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::string>> stopRecorder() override {
      auto __result = _swiftPart.stopRecorder();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::string>> startPlayer(const std::optional<std::string>& uri, const std::optional<std::unordered_map<std::string, std::string>>& httpHeaders) override {
      auto __result = _swiftPart.startPlayer(uri, httpHeaders);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::string>> stopPlayer() override {
      auto __result = _swiftPart.stopPlayer();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::string>> pausePlayer() override {
      auto __result = _swiftPart.pausePlayer();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::string>> resumePlayer() override {
      auto __result = _swiftPart.resumePlayer();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::string>> seekToPlayer(double time) override {
      auto __result = _swiftPart.seekToPlayer(std::forward<decltype(time)>(time));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::string>> setVolume(double volume) override {
      auto __result = _swiftPart.setVolume(std::forward<decltype(volume)>(volume));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::string>> setPlaybackSpeed(double playbackSpeed) override {
      auto __result = _swiftPart.setPlaybackSpeed(std::forward<decltype(playbackSpeed)>(playbackSpeed));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline void setSubscriptionDuration(double sec) override {
      auto __result = _swiftPart.setSubscriptionDuration(std::forward<decltype(sec)>(sec));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void addRecordBackListener(const std::function<void(const RecordBackType& /* recordingMeta */)>& callback) override {
      auto __result = _swiftPart.addRecordBackListener(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void removeRecordBackListener() override {
      auto __result = _swiftPart.removeRecordBackListener();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void addPlayBackListener(const std::function<void(const PlayBackType& /* playbackMeta */)>& callback) override {
      auto __result = _swiftPart.addPlayBackListener(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void removePlayBackListener() override {
      auto __result = _swiftPart.removePlayBackListener();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void addPlaybackEndListener(const std::function<void(const PlaybackEndType& /* playbackEndMeta */)>& callback) override {
      auto __result = _swiftPart.addPlaybackEndListener(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void removePlaybackEndListener() override {
      auto __result = _swiftPart.removePlaybackEndListener();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline std::string mmss(double secs) override {
      auto __result = _swiftPart.mmss(std::forward<decltype(secs)>(secs));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::string mmssss(double milisecs) override {
      auto __result = _swiftPart.mmssss(std::forward<decltype(milisecs)>(milisecs));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }

  private:
    NitroSound::HybridSoundSpec_cxx _swiftPart;
  };

} // namespace margelo::nitro::sound
