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

#pragma once

#include "HybridPlaybackEngineSpec.hpp"

// Forward declaration of `HybridPlaybackEngineSpec_cxx` to properly resolve imports.
namespace Aviation { class HybridPlaybackEngineSpec_cxx; }

// Forward declaration of `PlaybackState` to properly resolve imports.
namespace margelo::nitro::aviation { enum class PlaybackState; }
// Forward declaration of `MediaPosition` to properly resolve imports.
namespace margelo::nitro::aviation { struct MediaPosition; }
// Forward declaration of `HybridMediaItemSpec` to properly resolve imports.
namespace margelo::nitro::aviation { class HybridMediaItemSpec; }
// Forward declaration of `ItemSource` to properly resolve imports.
namespace margelo::nitro::aviation { enum class ItemSource; }
// Forward declaration of `SubtitleTrack` to properly resolve imports.
namespace margelo::nitro::aviation { struct SubtitleTrack; }
// Forward declaration of `AudioTrack` to properly resolve imports.
namespace margelo::nitro::aviation { struct AudioTrack; }
// Forward declaration of `RepeatMode` to properly resolve imports.
namespace margelo::nitro::aviation { enum class RepeatMode; }
// Forward declaration of `RemoteCommand` to properly resolve imports.
namespace margelo::nitro::aviation { enum class RemoteCommand; }
// Forward declaration of `NowPlayingInfo` to properly resolve imports.
namespace margelo::nitro::aviation { struct NowPlayingInfo; }
// Forward declaration of `HybridAudioSessionSpec` to properly resolve imports.
namespace margelo::nitro::aviation { class HybridAudioSessionSpec; }
// Forward declaration of `RemoteCommandEvent` to properly resolve imports.
namespace margelo::nitro::aviation { struct RemoteCommandEvent; }
// Forward declaration of `PlaybackMetricEvent` to properly resolve imports.
namespace margelo::nitro::aviation { struct PlaybackMetricEvent; }
// Forward declaration of `PlaybackMetricType` to properly resolve imports.
namespace margelo::nitro::aviation { enum class PlaybackMetricType; }
// Forward declaration of `TtffSource` to properly resolve imports.
namespace margelo::nitro::aviation { enum class TtffSource; }
// Forward declaration of `AvailableTracks` to properly resolve imports.
namespace margelo::nitro::aviation { struct AvailableTracks; }
// Forward declaration of `DomainEvent` to properly resolve imports.
namespace margelo::nitro::aviation { struct DomainEvent; }
// Forward declaration of `DomainEventType` to properly resolve imports.
namespace margelo::nitro::aviation { enum class DomainEventType; }
// Forward declaration of `AviationInterruptionMode` to properly resolve imports.
namespace margelo::nitro::aviation { enum class AviationInterruptionMode; }
// Forward declaration of `BecomingNoisyBehavior` to properly resolve imports.
namespace margelo::nitro::aviation { enum class BecomingNoisyBehavior; }
// Forward declaration of `VideoTrackSelection` to properly resolve imports.
namespace margelo::nitro::aviation { struct VideoTrackSelection; }
// Forward declaration of `VideoTrackSelectionType` to properly resolve imports.
namespace margelo::nitro::aviation { enum class VideoTrackSelectionType; }
// Forward declaration of `SubtitleTrackSelection` to properly resolve imports.
namespace margelo::nitro::aviation { struct SubtitleTrackSelection; }
// Forward declaration of `SubtitleTrackSelectionType` to properly resolve imports.
namespace margelo::nitro::aviation { enum class SubtitleTrackSelectionType; }
// Forward declaration of `AudioTrackSelection` to properly resolve imports.
namespace margelo::nitro::aviation { struct AudioTrackSelection; }
// Forward declaration of `AudioTrackSelectionType` to properly resolve imports.
namespace margelo::nitro::aviation { enum class AudioTrackSelectionType; }
// Forward declaration of `PreloadConfig` to properly resolve imports.
namespace margelo::nitro::aviation { struct PreloadConfig; }
// Forward declaration of `BufferConfig` to properly resolve imports.
namespace margelo::nitro::aviation { struct BufferConfig; }

#include <string>
#include "PlaybackState.hpp"
#include "MediaPosition.hpp"
#include <memory>
#include "HybridMediaItemSpec.hpp"
#include <optional>
#include "ItemSource.hpp"
#include "SubtitleTrack.hpp"
#include <vector>
#include "AudioTrack.hpp"
#include "RepeatMode.hpp"
#include <NitroModules/Promise.hpp>
#include "RemoteCommand.hpp"
#include "NowPlayingInfo.hpp"
#include "HybridAudioSessionSpec.hpp"
#include <functional>
#include "RemoteCommandEvent.hpp"
#include "PlaybackMetricEvent.hpp"
#include "PlaybackMetricType.hpp"
#include "TtffSource.hpp"
#include "AvailableTracks.hpp"
#include "DomainEvent.hpp"
#include "DomainEventType.hpp"
#include "AviationInterruptionMode.hpp"
#include "BecomingNoisyBehavior.hpp"
#include "VideoTrackSelection.hpp"
#include "VideoTrackSelectionType.hpp"
#include "SubtitleTrackSelection.hpp"
#include "SubtitleTrackSelectionType.hpp"
#include "AudioTrackSelection.hpp"
#include "AudioTrackSelectionType.hpp"
#include "PreloadConfig.hpp"
#include "BufferConfig.hpp"

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

namespace margelo::nitro::aviation {

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

  public:
    // Get the Swift part
    inline Aviation::HybridPlaybackEngineSpec_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<HybridPlaybackEngineSpecSwift>(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 getEngineId() noexcept override {
      auto __result = _swiftPart.getEngineId();
      return __result;
    }
    inline PlaybackState getState() noexcept override {
      auto __result = _swiftPart.getState();
      return static_cast<PlaybackState>(__result);
    }
    inline MediaPosition getMediaPosition() noexcept override {
      return _swiftPart.getMediaPosition();
    }
    inline std::optional<std::shared_ptr<HybridMediaItemSpec>> getCurrentItem() noexcept override {
      auto __result = _swiftPart.getCurrentItem();
      return __result;
    }
    inline ItemSource getCurrentItemSource() noexcept override {
      auto __result = _swiftPart.getCurrentItemSource();
      return static_cast<ItemSource>(__result);
    }
    inline bool getIsLive() noexcept override {
      return _swiftPart.isLive();
    }
    inline bool getIsPlaying() noexcept override {
      return _swiftPart.isPlaying();
    }
    inline bool getIsPaused() noexcept override {
      return _swiftPart.isPaused();
    }
    inline bool getIsLoaded() noexcept override {
      return _swiftPart.isLoaded();
    }
    inline std::vector<SubtitleTrack> getAvailableSubtitleTracks() noexcept override {
      auto __result = _swiftPart.getAvailableSubtitleTracks();
      return __result;
    }
    inline std::vector<AudioTrack> getAvailableAudioTracks() noexcept override {
      auto __result = _swiftPart.getAvailableAudioTracks();
      return __result;
    }
    inline double getVolume() noexcept override {
      return _swiftPart.getVolume();
    }
    inline void setVolume(double volume) noexcept override {
      _swiftPart.setVolume(std::forward<decltype(volume)>(volume));
    }
    inline double getRate() noexcept override {
      return _swiftPart.getRate();
    }
    inline void setRate(double rate) noexcept override {
      _swiftPart.setRate(std::forward<decltype(rate)>(rate));
    }
    inline bool getMuted() noexcept override {
      return _swiftPart.getMuted();
    }
    inline void setMuted(bool muted) noexcept override {
      _swiftPart.setMuted(std::forward<decltype(muted)>(muted));
    }
    inline bool getLoop() noexcept override {
      return _swiftPart.getLoop();
    }
    inline void setLoop(bool loop) noexcept override {
      _swiftPart.setLoop(std::forward<decltype(loop)>(loop));
    }
    inline std::vector<std::shared_ptr<HybridMediaItemSpec>> getQueueItems() noexcept override {
      auto __result = _swiftPart.getQueueItems();
      return __result;
    }
    inline double getQueueIndex() noexcept override {
      return _swiftPart.getQueueIndex();
    }
    inline double getQueueCount() noexcept override {
      return _swiftPart.getQueueCount();
    }
    inline RepeatMode getRepeatMode() noexcept override {
      auto __result = _swiftPart.getRepeatMode();
      return static_cast<RepeatMode>(__result);
    }
    inline void setRepeatMode(RepeatMode repeatMode) noexcept override {
      _swiftPart.setRepeatMode(static_cast<int>(repeatMode));
    }
    inline bool getShuffleEnabled() noexcept override {
      return _swiftPart.getShuffleEnabled();
    }
    inline void setShuffleEnabled(bool shuffleEnabled) noexcept override {
      _swiftPart.setShuffleEnabled(std::forward<decltype(shuffleEnabled)>(shuffleEnabled));
    }

  public:
    // Methods
    inline std::shared_ptr<Promise<void>> load(const std::shared_ptr<HybridMediaItemSpec>& item) override {
      auto __result = _swiftPart.load(item);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> loadAndPlay(const std::shared_ptr<HybridMediaItemSpec>& item) override {
      auto __result = _swiftPart.loadAndPlay(item);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> play() override {
      auto __result = _swiftPart.play();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> 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<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<void>> seekTo(double positionMs) override {
      auto __result = _swiftPart.seekTo(std::forward<decltype(positionMs)>(positionMs));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline void release() override {
      auto __result = _swiftPart.release();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void activateDefaultDecoder() override {
      auto __result = _swiftPart.activateDefaultDecoder();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setQueue(const std::vector<std::shared_ptr<HybridMediaItemSpec>>& items) override {
      auto __result = _swiftPart.setQueue(items);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void addToQueue(const std::shared_ptr<HybridMediaItemSpec>& item) override {
      auto __result = _swiftPart.addToQueue(item);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void insertInQueue(const std::shared_ptr<HybridMediaItemSpec>& item, double afterIndex) override {
      auto __result = _swiftPart.insertInQueue(item, std::forward<decltype(afterIndex)>(afterIndex));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void removeFromQueue(double index) override {
      auto __result = _swiftPart.removeFromQueue(std::forward<decltype(index)>(index));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void moveInQueue(double fromIndex, double toIndex) override {
      auto __result = _swiftPart.moveInQueue(std::forward<decltype(fromIndex)>(fromIndex), std::forward<decltype(toIndex)>(toIndex));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void clearQueue() override {
      auto __result = _swiftPart.clearQueue();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline std::shared_ptr<Promise<void>> skipToNext() override {
      auto __result = _swiftPart.skipToNext();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> skipToPrevious() override {
      auto __result = _swiftPart.skipToPrevious();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> skipToIndex(double index, bool autoPlay) override {
      auto __result = _swiftPart.skipToIndex(std::forward<decltype(index)>(index), std::forward<decltype(autoPlay)>(autoPlay));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline void setEnabledCommands(const std::vector<RemoteCommand>& commands) override {
      auto __result = _swiftPart.setEnabledCommands(commands);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setCompactCommands(const std::vector<RemoteCommand>& commands) override {
      auto __result = _swiftPart.setCompactCommands(commands);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setSkipIntervalMs(double intervalMs) override {
      auto __result = _swiftPart.setSkipIntervalMs(std::forward<decltype(intervalMs)>(intervalMs));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void updateNowPlaying(const NowPlayingInfo& info) override {
      auto __result = _swiftPart.updateNowPlaying(std::forward<decltype(info)>(info));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void overrideRemoteCommand(RemoteCommand command) override {
      auto __result = _swiftPart.overrideRemoteCommand(static_cast<int>(command));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void clearRemoteCommandOverride(RemoteCommand command) override {
      auto __result = _swiftPart.clearRemoteCommandOverride(static_cast<int>(command));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setAudioSession(const std::shared_ptr<HybridAudioSessionSpec>& session) override {
      auto __result = _swiftPart.setAudioSession(session);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void clearCallbacks() override {
      auto __result = _swiftPart.clearCallbacks();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void onStateChange(const std::function<void(PlaybackState /* state */)>& callback) override {
      auto __result = _swiftPart.onStateChange(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void onMediaPositionChange(const std::function<void(const MediaPosition& /* position */)>& callback) override {
      auto __result = _swiftPart.onMediaPositionChange(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void onCurrentItemChange(const std::function<void(const std::optional<std::shared_ptr<HybridMediaItemSpec>>& /* item */, ItemSource /* source */)>& callback) override {
      auto __result = _swiftPart.onCurrentItemChange(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void onRemoteCommand(const std::function<void(const RemoteCommandEvent& /* event */)>& callback) override {
      auto __result = _swiftPart.onRemoteCommand(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void onError(const std::function<void(const std::string& /* message */, const std::string& /* code */)>& callback) override {
      auto __result = _swiftPart.onError(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void onPlaybackEnded(const std::function<void()>& callback) override {
      auto __result = _swiftPart.onPlaybackEnded(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void onQueueEnd(const std::function<void()>& callback) override {
      auto __result = _swiftPart.onQueueEnd(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void onQueueChange(const std::function<void()>& callback) override {
      auto __result = _swiftPart.onQueueChange(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void onPlaybackMetric(const std::function<void(const PlaybackMetricEvent& /* event */)>& callback) override {
      auto __result = _swiftPart.onPlaybackMetric(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void onTracksAvailable(const std::function<void(const AvailableTracks& /* tracks */)>& callback) override {
      auto __result = _swiftPart.onTracksAvailable(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void onDomainEvent(const std::function<void(const DomainEvent& /* event */)>& callback) override {
      auto __result = _swiftPart.onDomainEvent(callback);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setInterruptionMode(AviationInterruptionMode mode) override {
      auto __result = _swiftPart.setInterruptionMode(static_cast<int>(mode));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setBecomingNoisyBehavior(BecomingNoisyBehavior behavior) override {
      auto __result = _swiftPart.setBecomingNoisyBehavior(static_cast<int>(behavior));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void selectVideoTrack(const VideoTrackSelection& selection) override {
      auto __result = _swiftPart.selectVideoTrack(std::forward<decltype(selection)>(selection));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void selectSubtitleTrack(const SubtitleTrackSelection& selection) override {
      auto __result = _swiftPart.selectSubtitleTrack(std::forward<decltype(selection)>(selection));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void selectAudioTrack(const AudioTrackSelection& selection) override {
      auto __result = _swiftPart.selectAudioTrack(std::forward<decltype(selection)>(selection));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline std::shared_ptr<Promise<void>> clearCache() override {
      auto __result = _swiftPart.clearCache();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline double getCacheSize() override {
      auto __result = _swiftPart.getCacheSize();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline bool isCached(const std::string& uri) override {
      auto __result = _swiftPart.isCached(uri);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline void setCacheEnabled(bool enabled) override {
      auto __result = _swiftPart.setCacheEnabled(std::forward<decltype(enabled)>(enabled));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void preload(const std::vector<std::shared_ptr<HybridMediaItemSpec>>& items) override {
      auto __result = _swiftPart.preload(items);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setPreloadConfig(const PreloadConfig& config) override {
      auto __result = _swiftPart.setPreloadConfig(std::forward<decltype(config)>(config));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setBufferConfig(const BufferConfig& config) override {
      auto __result = _swiftPart.setBufferConfig(std::forward<decltype(config)>(config));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setCacheMaxSize(double sizeBytes) override {
      auto __result = _swiftPart.setCacheMaxSize(std::forward<decltype(sizeBytes)>(sizeBytes));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }
    inline void setPreloadEnabled(bool enabled) override {
      auto __result = _swiftPart.setPreloadEnabled(std::forward<decltype(enabled)>(enabled));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
    }

  private:
    Aviation::HybridPlaybackEngineSpec_cxx _swiftPart;
  };

} // namespace margelo::nitro::aviation
