/*
    Copyright (C) 2024 Apple Inc. All Rights Reserved.
*/

#pragma once

#ifndef ACCESSORY_SETUP_KIT_INDIRECT_INCLUDES
#error "Please #import <AccessorySetupKit/AccessorySetupKit.h> instead of this file directly."
#endif

#import <AccessorySetupKit/ASCommon.h>
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@class ASAccessory;
@class ASAccessorySettings;
@class ASDiscoveryDescriptor;
@class ASAccessoryEvent;
@class ASAccessorySession;
@class ASDiscoveredDisplayItem;
@class ASMigrationDisplayItem;
@class ASPickerDisplayItem;
@class ASPickerDisplaySettings;

//===========================================================================================================================
/// Manages accessories.
AS_EXTERN
API_AVAILABLE( ios( 18.0 ) ) API_UNAVAILABLE(macos, macCatalyst, watchos, tvos, visionos)
NS_SWIFT_SENDABLE
@interface ASAccessorySession : NSObject

/// An array of previously-selected accessories for this application.
///
/// To monitor for changes in this list, use your event handler to watch for the events ``ASAccessoryEventType/accessoryAdded``, ``ASAccessoryEventType/accessoryChanged``, and ``ASAccessoryEventType/accessoryRemoved``.
@property (readonly, copy, nonatomic) NSArray<ASAccessory *> *accessories;

/// Settings that affect the display of the accessory picker.
///
/// Use this property to configure settings like the picker timeout.
@property (readwrite, copy, nullable, nonatomic) ASPickerDisplaySettings *pickerDisplaySettings
API_AVAILABLE( ios( 26.0 ) ) API_UNAVAILABLE(macos, macCatalyst, watchos, tvos, visionos);

/// Activate the session and start delivering events to an event handler.
/// - Parameters:
///   - queue: The dispatch the session uses to deliver events to `eventHandler`.
///   - eventHandler: A closure or block that receives events generated by the session. Each callback to the event handler provides an ``ASAccessoryEvent`` as a parameter, and expects no return value.
- (void) activateWithQueue:(dispatch_queue_t) queue eventHandler:(void(^)(ASAccessoryEvent *event)) eventHandler
NS_SWIFT_NAME(activate(on:eventHandler:));

/// Invalidate the session by stopping any operations.
///
/// This call breaks any retain cycles. The session is unusable after calling `invalidate`.
- (void) invalidate;

/// Present a picker that shows accessories managed by a Device Discovery Extension in your app.
///
/// Use this method when your app includes a <doc://com.apple.documentation/documentation/devicediscoveryextension> for its supported accessories. If your app doesn't use DDE, call ``showPickerForDisplayItems:completionHandler:`` with an array of ``ASPickerDisplayItem-c.class`` instances instead.
///
/// The session's event handler receives events when this picker displays and dismisses, as well as when the person using the app picks an accessory.
///
/// - Parameters:
///   - completionHandler: A block or closure that the picker calls when it completes the operation. The completion handler receives an <doc://com.apple.documentation/documentation/Foundation/NSError> instance if the picker encounters an error.
- (void) showPickerWithCompletionHandler:(void(^)(NSError * _Nullable error)) completionHandler
NS_SWIFT_NAME(showPicker(completionHandler:));

/// Present a picker that shows discovered accessories matching an array of display items.
///
/// The session's event handler receives events when this picker displays and dismisses, as well as when the person using the app picks an accessory.
///
/// To migrate previously-configured accessories to AccessorySetupKit, add instances of ``ASMigrationDisplayItem`` to the `displayItems` array.
/// - Parameters:
///   - displayItems: An array of ``ASPickerDisplayItem`` instances describing accessories your app can set up. The picker displays only discovered accessories that match the properties of items in this array.
///   - completionHandler: A block or closure that the picker calls when it completes the operation. The completion handler receives an <doc://com.apple.documentation/documentation/Foundation/NSError> instance if the picker encounters an error.
- (void) showPickerForDisplayItems:(NSArray<ASPickerDisplayItem *> *) displayItems
				  completionHandler:(void(^)(NSError * _Nullable error)) completionHandler
NS_SWIFT_NAME(showPicker(for:completionHandler:));

/// Finish authorization of a partially-setup accessory.
///
/// Use this method in scenarios where an accessory has multiple wireless interfaces. For example, when an accessory has both Bluetooth and Wi-Fi, and your descriptor may only provides an SSID prefix. In this case, the Bluetooth interface onboards first and your app needs to then finish authorization with the full SSID.
- (void) finishAuthorization:(ASAccessory *) accessory
                    settings:(ASAccessorySettings *) settings
           completionHandler:(void(^)(NSError * _Nullable error)) completionHandler
NS_SWIFT_NAME(finishAuthorization(for:settings:completionHandler:));

/// End authorization of a partially-configured accessory as a failure.
- (void) failAuthorization:(ASAccessory *) accessory
         completionHandler:(void(^)(NSError * _Nullable error)) completionHandler
NS_SWIFT_NAME(failAuthorization(for:completionHandler:));

/// Removes an accessory.
///
/// - Parameters:
///   - accessory: The accessory to remove.
///   - completionHandler: A block or closure that executes after the remove operation completes. The completion handler receives an <doc://com.apple.documentation/documentation/Foundation/NSError> instance if the remove operation encounters an error.
- (void) removeAccessory:(ASAccessory *) accessory
       completionHandler:(void(^)(NSError * _Nullable error)) completionHandler
NS_SWIFT_NAME(removeAccessory(_:completionHandler:));

/// Displays a view to rename an accessory.
///
/// To rename a Wi-Fi SSID with this method, use the option ``ASAccessory/RenameOptions/ssid``.
///
/// - Parameters:
///   - accessory: The accessory to rename.
///   - renameOptions: Options that affect the behavior of the rename operation.
///   - completionHandler: A block or closure that executes after the rename operation completes. The completion handler receives an <doc://com.apple.documentation/documentation/Foundation/NSError> instance if the rename operation encounters an error.
- (void) renameAccessory:(ASAccessory *) accessory
                 options:(ASAccessoryRenameOptions) renameOptions
       completionHandler:(void(^)(NSError * _Nullable error)) completionHandler
NS_SWIFT_NAME(renameAccessory(_:options:completionHandler:));

/// Displays a view to upgrade an accessory with additional technology permissions.
///
/// Call this method to upgrade previously-added SSID-based accessories to use WiFi Aware.
///
/// - Parameters:
///   - accessory: The accessory to update.
///   - descriptor: An updated descriptor that the picker uses to add new technology authorization for the provided accessory.
///   - completionHandler: A block or closure that executes after the picker is shown. The completion handler receives an <doc://com.apple.documentation/documentation/Foundation/NSError> instance if the upgrade operation encounters an error. In Swift, you can omit the completion handler by calling the method asynchronously and catching any error thrown by the method.
- (void) updateAuthorization:(ASAccessory *) accessory
                  descriptor:(ASDiscoveryDescriptor *) descriptor
           completionHandler:(void(^)(NSError * _Nullable error)) completionHandler
NS_SWIFT_NAME(updateAuthorization(for:descriptor:completionHandler:))
API_AVAILABLE( ios( 26.0 ) ) API_UNAVAILABLE(macos, macCatalyst, watchos, tvos, visionos);

/// Updates the picker with app-filtered accessories.
///
/// You use this method when your picker uses the ``ASPickerDisplaySettings/Options/filterDiscoveryResults`` option to enable manual filtering of discovered accessories.
/// After creating customized ``ASDiscoveredDisplayItem`` instances for included accessories, call this method to update the picker to show your app-filtered accessories with updated assets.
///
/// - Parameters:
///   - displayItems: The app-filtered accessories to show in the picker.
///   - completionHandler: A block or closure that executes after the updatePicker operation completes. The completion handler receives an <doc://com.apple.documentation/documentation/Foundation/NSError> instance if the operation encounters an error.

- (void) updatePickerShowingDiscoveredDisplayItems:(NSArray<ASDiscoveredDisplayItem *> *)displayItems
                                 completionHandler:(void(^)(NSError * _Nullable error)) completionHandler
NS_SWIFT_NAME(updatePicker(showing:completionHandler:))
API_AVAILABLE( ios( 26.1 ) ) API_UNAVAILABLE(macos, macCatalyst, watchos, tvos, visionos);

/// Finish the discovery session in the picker and show a timeout error.
///
/// Use this method if you previously set the picker display setting ``ASPickerDisplaySettings/discoveryTimeout`` to ``ASPickerDisplaySettings/DiscoveryTimeout/unbounded`` in order to perform manual filtering of discovered accessories.
/// Calling this method finishes the discovery session in the picker and shows a timeout error if the session didn't find any desired accessories.
///
/// Calling this method after updating the picker with discovered accessories has no effect.
///
/// - Parameters:
///   - completionHandler: A block or closure that executes after this operation completes. The completion handler receives an <doc://com.apple.documentation/documentation/Foundation/NSError> instance if the operation encounters an error.
- (void) finishPickerDiscovery:(void(^)(NSError * _Nullable error)) completionHandler
NS_SWIFT_NAME(finishPickerDiscovery(completionHandler:))
API_AVAILABLE( ios( 26.1 ) ) API_UNAVAILABLE(macos, macCatalyst, watchos, tvos, visionos);

@end

NS_ASSUME_NONNULL_END
