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

#pragma once

#include "HybridOneAudioSpec.hpp"

// Forward declaration of `HybridOneAudioSpec_cxx` to properly resolve imports.
namespace One { class HybridOneAudioSpec_cxx; }

// Forward declaration of `AudioRecordingPermission` to properly resolve imports.
namespace margelo::nitro::one { enum class AudioRecordingPermission; }
// Forward declaration of `AudioPlaybackStatus` to properly resolve imports.
namespace margelo::nitro::one { struct AudioPlaybackStatus; }
// Forward declaration of `AudioPlaybackState` to properly resolve imports.
namespace margelo::nitro::one { enum class AudioPlaybackState; }
// Forward declaration of `AudioRecordingStatus` to properly resolve imports.
namespace margelo::nitro::one { struct AudioRecordingStatus; }
// Forward declaration of `AudioRecordingState` to properly resolve imports.
namespace margelo::nitro::one { enum class AudioRecordingState; }
// Forward declaration of `AudioRecordingResult` to properly resolve imports.
namespace margelo::nitro::one { struct AudioRecordingResult; }
// Forward declaration of `AudioInterruptionEvent` to properly resolve imports.
namespace margelo::nitro::one { struct AudioInterruptionEvent; }
// Forward declaration of `AudioInterruptionType` to properly resolve imports.
namespace margelo::nitro::one { enum class AudioInterruptionType; }
// Forward declaration of `AudioNowPlayingInfo` to properly resolve imports.
namespace margelo::nitro::one { struct AudioNowPlayingInfo; }
// Forward declaration of `AudioRemoteCommandEvent` to properly resolve imports.
namespace margelo::nitro::one { struct AudioRemoteCommandEvent; }
// Forward declaration of `AudioRemoteCommandType` to properly resolve imports.
namespace margelo::nitro::one { enum class AudioRemoteCommandType; }
// Forward declaration of `AudioPlayerStatus` to properly resolve imports.
namespace margelo::nitro::one { struct AudioPlayerStatus; }
// Forward declaration of `PitchCorrectionQuality` to properly resolve imports.
namespace margelo::nitro::one { enum class PitchCorrectionQuality; }

#include "AudioRecordingPermission.hpp"
#include <NitroModules/Promise.hpp>
#include "AudioPlaybackStatus.hpp"
#include "AudioPlaybackState.hpp"
#include <string>
#include <optional>
#include "AudioRecordingStatus.hpp"
#include "AudioRecordingState.hpp"
#include "AudioRecordingResult.hpp"
#include <functional>
#include "AudioInterruptionEvent.hpp"
#include "AudioInterruptionType.hpp"
#include "AudioNowPlayingInfo.hpp"
#include "AudioRemoteCommandEvent.hpp"
#include "AudioRemoteCommandType.hpp"
#include <unordered_map>
#include "AudioPlayerStatus.hpp"
#include "PitchCorrectionQuality.hpp"

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

namespace margelo::nitro::one {

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

  public:
    // Get the Swift part
    inline One::HybridOneAudioSpec_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<HybridOneAudioSpecSwift>(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<AudioRecordingPermission>> getRecordingPermissionStatus() override {
      auto __result = _swiftPart.getRecordingPermissionStatus();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<AudioRecordingPermission>> requestRecordingPermission() override {
      auto __result = _swiftPart.requestRecordingPermission();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<AudioPlaybackStatus>> play(const std::string& uri) override {
      auto __result = _swiftPart.play(uri);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<AudioPlaybackStatus>> getPlaybackStatus() override {
      auto __result = _swiftPart.getPlaybackStatus();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<AudioPlaybackStatus>> pause() override {
      auto __result = _swiftPart.pause();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<AudioPlaybackStatus>> resume() override {
      auto __result = _swiftPart.resume();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<AudioPlaybackStatus>> seek(double positionMs) override {
      auto __result = _swiftPart.seek(std::forward<decltype(positionMs)>(positionMs));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> stop() override {
      auto __result = _swiftPart.stop();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<AudioRecordingStatus>> startRecording() override {
      auto __result = _swiftPart.startRecording();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<AudioRecordingStatus>> getRecordingStatus() override {
      auto __result = _swiftPart.getRecordingStatus();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<AudioRecordingStatus>> pauseRecording() override {
      auto __result = _swiftPart.pauseRecording();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<AudioRecordingStatus>> resumeRecording() override {
      auto __result = _swiftPart.resumeRecording();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<AudioRecordingResult>> stopRecording() override {
      auto __result = _swiftPart.stopRecording();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::function<void()> addInterruptionListener(const std::function<void(const AudioInterruptionEvent& /* event */)>& onEvent) override {
      auto __result = _swiftPart.addInterruptionListener(onEvent);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> setNowPlayingInfo(const AudioNowPlayingInfo& info) override {
      auto __result = _swiftPart.setNowPlayingInfo(std::forward<decltype(info)>(info));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> clearNowPlayingInfo() override {
      auto __result = _swiftPart.clearNowPlayingInfo();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::function<void()> addRemoteCommandListener(const std::function<void(const AudioRemoteCommandEvent& /* event */)>& onEvent) override {
      auto __result = _swiftPart.addRemoteCommandListener(onEvent);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::string createPlayer(const std::optional<std::string>& sourceUri, const std::optional<std::unordered_map<std::string, std::string>>& headers) override {
      auto __result = _swiftPart.createPlayer(sourceUri, headers);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline void playerPlay(const std::string& playerId) override {
      auto __result = _swiftPart.playerPlay(playerId);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void playerPause(const std::string& playerId) override {
      auto __result = _swiftPart.playerPause(playerId);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline std::shared_ptr<Promise<void>> playerSeek(const std::string& playerId, double seconds, std::optional<double> toleranceBeforeMs, std::optional<double> toleranceAfterMs) override {
      auto __result = _swiftPart.playerSeek(playerId, std::forward<decltype(seconds)>(seconds), toleranceBeforeMs, toleranceAfterMs);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline void playerReplace(const std::string& playerId, const std::optional<std::string>& sourceUri, const std::optional<std::unordered_map<std::string, std::string>>& headers) override {
      auto __result = _swiftPart.playerReplace(playerId, sourceUri, headers);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void removePlayer(const std::string& playerId) override {
      auto __result = _swiftPart.removePlayer(playerId);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline AudioPlayerStatus getPlayerStatus(const std::string& playerId) override {
      auto __result = _swiftPart.getPlayerStatus(playerId);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline void setPlayerRate(const std::string& playerId, double rate, std::optional<PitchCorrectionQuality> pitchQuality) override {
      auto __result = _swiftPart.setPlayerRate(playerId, std::forward<decltype(rate)>(rate), pitchQuality);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setPlayerVolume(const std::string& playerId, double volume) override {
      auto __result = _swiftPart.setPlayerVolume(playerId, std::forward<decltype(volume)>(volume));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setPlayerMuted(const std::string& playerId, bool muted) override {
      auto __result = _swiftPart.setPlayerMuted(playerId, std::forward<decltype(muted)>(muted));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setPlayerLoop(const std::string& playerId, bool loop) override {
      auto __result = _swiftPart.setPlayerLoop(playerId, std::forward<decltype(loop)>(loop));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setPlayerPitchCorrection(const std::string& playerId, bool enabled) override {
      auto __result = _swiftPart.setPlayerPitchCorrection(playerId, std::forward<decltype(enabled)>(enabled));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }

  private:
    One::HybridOneAudioSpec_cxx _swiftPart;
  };

} // namespace margelo::nitro::one
