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

#pragma once

#if __has_include(<NitroModules/HybridObject.hpp>)
#include <NitroModules/HybridObject.hpp>
#else
#error NitroModules cannot be found! Are you sure you installed NitroModules properly?
#endif

// 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 `AudioRecordingStatus` to properly resolve imports.
namespace margelo::nitro::one { struct AudioRecordingStatus; }
// 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 `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 `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 <string>
#include "AudioRecordingStatus.hpp"
#include "AudioRecordingResult.hpp"
#include <functional>
#include "AudioInterruptionEvent.hpp"
#include "AudioNowPlayingInfo.hpp"
#include "AudioRemoteCommandEvent.hpp"
#include <optional>
#include <unordered_map>
#include "AudioPlayerStatus.hpp"
#include "PitchCorrectionQuality.hpp"

namespace margelo::nitro::one {

  using namespace margelo::nitro;

  /**
   * An abstract base class for `OneAudio`
   * Inherit this class to create instances of `HybridOneAudioSpec` in C++.
   * You must explicitly call `HybridObject`'s constructor yourself, because it is virtual.
   * @example
   * ```cpp
   * class HybridOneAudio: public HybridOneAudioSpec {
   * public:
   *   HybridOneAudio(...): HybridObject(TAG) { ... }
   *   // ...
   * };
   * ```
   */
  class HybridOneAudioSpec: public virtual HybridObject {
    public:
      // Constructor
      explicit HybridOneAudioSpec(): HybridObject(TAG) { }

      // Destructor
      ~HybridOneAudioSpec() override = default;

    public:
      // Properties
      

    public:
      // Methods
      virtual std::shared_ptr<Promise<AudioRecordingPermission>> getRecordingPermissionStatus() = 0;
      virtual std::shared_ptr<Promise<AudioRecordingPermission>> requestRecordingPermission() = 0;
      virtual std::shared_ptr<Promise<AudioPlaybackStatus>> play(const std::string& uri) = 0;
      virtual std::shared_ptr<Promise<AudioPlaybackStatus>> getPlaybackStatus() = 0;
      virtual std::shared_ptr<Promise<AudioPlaybackStatus>> pause() = 0;
      virtual std::shared_ptr<Promise<AudioPlaybackStatus>> resume() = 0;
      virtual std::shared_ptr<Promise<AudioPlaybackStatus>> seek(double positionMs) = 0;
      virtual std::shared_ptr<Promise<void>> stop() = 0;
      virtual std::shared_ptr<Promise<AudioRecordingStatus>> startRecording() = 0;
      virtual std::shared_ptr<Promise<AudioRecordingStatus>> getRecordingStatus() = 0;
      virtual std::shared_ptr<Promise<AudioRecordingStatus>> pauseRecording() = 0;
      virtual std::shared_ptr<Promise<AudioRecordingStatus>> resumeRecording() = 0;
      virtual std::shared_ptr<Promise<AudioRecordingResult>> stopRecording() = 0;
      virtual std::function<void()> addInterruptionListener(const std::function<void(const AudioInterruptionEvent& /* event */)>& onEvent) = 0;
      virtual std::shared_ptr<Promise<void>> setNowPlayingInfo(const AudioNowPlayingInfo& info) = 0;
      virtual std::shared_ptr<Promise<void>> clearNowPlayingInfo() = 0;
      virtual std::function<void()> addRemoteCommandListener(const std::function<void(const AudioRemoteCommandEvent& /* event */)>& onEvent) = 0;
      virtual std::string createPlayer(const std::optional<std::string>& sourceUri, const std::optional<std::unordered_map<std::string, std::string>>& headers) = 0;
      virtual void playerPlay(const std::string& playerId) = 0;
      virtual void playerPause(const std::string& playerId) = 0;
      virtual std::shared_ptr<Promise<void>> playerSeek(const std::string& playerId, double seconds, std::optional<double> toleranceBeforeMs, std::optional<double> toleranceAfterMs) = 0;
      virtual void playerReplace(const std::string& playerId, const std::optional<std::string>& sourceUri, const std::optional<std::unordered_map<std::string, std::string>>& headers) = 0;
      virtual void removePlayer(const std::string& playerId) = 0;
      virtual AudioPlayerStatus getPlayerStatus(const std::string& playerId) = 0;
      virtual void setPlayerRate(const std::string& playerId, double rate, std::optional<PitchCorrectionQuality> pitchQuality) = 0;
      virtual void setPlayerVolume(const std::string& playerId, double volume) = 0;
      virtual void setPlayerMuted(const std::string& playerId, bool muted) = 0;
      virtual void setPlayerLoop(const std::string& playerId, bool loop) = 0;
      virtual void setPlayerPitchCorrection(const std::string& playerId, bool enabled) = 0;

    protected:
      // Hybrid Setup
      void loadHybridMethods() override;

    protected:
      // Tag for logging
      static constexpr auto TAG = "OneAudio";
  };

} // namespace margelo::nitro::one
