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

#pragma once

#include "HybridOneLocationSpec.hpp"

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

// Forward declaration of `LocationPermissionStatus` to properly resolve imports.
namespace margelo::nitro::one { enum class LocationPermissionStatus; }
// Forward declaration of `LocationPosition` to properly resolve imports.
namespace margelo::nitro::one { struct LocationPosition; }
// Forward declaration of `LocationPlace` to properly resolve imports.
namespace margelo::nitro::one { struct LocationPlace; }
// Forward declaration of `LocationRegion` to properly resolve imports.
namespace margelo::nitro::one { struct LocationRegion; }
// Forward declaration of `RegionCenter` to properly resolve imports.
namespace margelo::nitro::one { struct RegionCenter; }
// Forward declaration of `RegionState` to properly resolve imports.
namespace margelo::nitro::one { enum class RegionState; }

#include "LocationPermissionStatus.hpp"
#include <NitroModules/Promise.hpp>
#include "LocationPosition.hpp"
#include <functional>
#include <string>
#include "LocationPlace.hpp"
#include <vector>
#include <optional>
#include "LocationRegion.hpp"
#include "RegionCenter.hpp"
#include "RegionState.hpp"

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

namespace margelo::nitro::one {

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

  public:
    // Get the Swift part
    inline One::HybridOneLocationSpec_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<HybridOneLocationSpecSwift>(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 LocationPermissionStatus getPermissionStatus() override {
      auto __result = _swiftPart.getPermissionStatus();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<LocationPermissionStatus>> requestWhenInUsePermission() override {
      auto __result = _swiftPart.requestWhenInUsePermission();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<LocationPermissionStatus>> requestAlwaysAuthorization() override {
      auto __result = _swiftPart.requestAlwaysAuthorization();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<LocationPosition>> getCurrentPosition() override {
      auto __result = _swiftPart.getCurrentPosition();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::function<void()> addPositionListener(const std::function<void(const LocationPosition& /* position */)>& onPosition, const std::function<void(const std::string& /* code */, const std::string& /* message */)>& onError, bool background) override {
      auto __result = _swiftPart.addPositionListener(onPosition, onError, std::forward<decltype(background)>(background));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::vector<LocationPlace>>> geocodeAddress(const std::string& address) override {
      auto __result = _swiftPart.geocodeAddress(address);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<std::vector<LocationPlace>>> reverseGeocode(double latitude, double longitude) override {
      auto __result = _swiftPart.reverseGeocode(std::forward<decltype(latitude)>(latitude), std::forward<decltype(longitude)>(longitude));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> startMonitoring(const LocationRegion& region) override {
      auto __result = _swiftPart.startMonitoring(std::forward<decltype(region)>(region));
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<void>> stopMonitoring(const std::string& identifier) override {
      auto __result = _swiftPart.stopMonitoring(identifier);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::vector<LocationRegion> monitoredRegions() override {
      auto __result = _swiftPart.monitoredRegions();
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::shared_ptr<Promise<RegionState>> requestState(const std::string& identifier) override {
      auto __result = _swiftPart.requestState(identifier);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::function<void()> addDidEnterRegionListener(const std::function<void(const LocationRegion& /* region */)>& listener) override {
      auto __result = _swiftPart.addDidEnterRegionListener(listener);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }
    inline std::function<void()> addDidExitRegionListener(const std::function<void(const LocationRegion& /* region */)>& listener) override {
      auto __result = _swiftPart.addDidExitRegionListener(listener);
      if (__result.hasError()) [[unlikely]] {
        std::rethrow_exception(__result.error());
      }
      auto __value = std::move(__result.value());
      return __value;
    }

  private:
    One::HybridOneLocationSpec_cxx _swiftPart;
  };

} // namespace margelo::nitro::one
