//
//  CLMovieDownloadSet.h
//  mpl
//
//  Created by Emil Pettersson on 08/04/16.
//  Copyright © 2016 castLabs GmbH. All rights reserved.
//

#import "CLDownloadStats.h"
#import "CLMovie.h"
#import "CLMovieDownloadProperties.h"

@class CLMovieDownloadSet;

/**
 * Delegate protocol for implementing a delegate to CLMovieDownloadSet.
 */
@protocol CLMovieDownloadSetDelegate <NSObject>

@optional

/**
 * Called when download set changes its status (see CLDownloadStatus).
 */
- (void)movieDownloadSet:(nonnull CLMovieDownloadSet*)set didChangeStatus:(CLDownloadStatus)status;


/**
 * Called when the download set completes (or fails) downloading.
 */
- (void)movieDownloadSet:(nonnull CLMovieDownloadSet*)set didCompleteWithError:(nullable NSError*)error;

/**
 * Called when a quality completes (or fails) downloading.
 */
- (void)movieDownloadSet:(nonnull CLMovieDownloadSet*)set didCompleteQuality:(nonnull CLQuality*)quality withError:(nullable NSError*)error;

/**
 * Called with recalculated progress if download information is updated for a set.
 */
- (void)movieDownloadSet:(nonnull CLMovieDownloadSet*)set didUpdateProgress:(CLDownloadProgress)progress;

/**
 * Called with recalculated progress if download information is updated for a quality.
 */
- (void)movieDownloadSet:(nonnull CLMovieDownloadSet*)set didUpdateProgress:(CLDownloadProgress)progress
              forQuality:(nonnull CLQuality*)quality;

@end

#pragma mark -

/**
 * Class representing a movie download.
 */
@interface CLMovieDownloadSet : NSObject <CLDownloadStats>

#pragma mark Properties

/**
 * A dictionary of extra headers that will be included in each URL request (overrides entries from
 * the CLMovieDownloader).
 */
@property (nullable) NSDictionary<NSString*, NSString*>* additionalHeaders;

/**
 * The movie represented by this download set.
 */
@property (nonnull, readonly) CLMovie* movie;

/**
 * The status of the download set (see CLDownloadStatus).
 */
@property (readonly) CLDownloadStatus status;

/**
 * The download set delegate.
 */
@property (nullable, weak) id<CLMovieDownloadSetDelegate> delegate;

/**
 * The total size of the movie (if known, otherwise CLDownloadStatsSizeUnknown).
 */
@property (readonly) CLDownloadSize totalSize;

/**
 * A user defined object.
 */
@property (nullable) id userObject;

/**
 * Access the properties for this set, both automatic and custom.
 */
@property (nonnull, readonly) CLMutableMovieDownloadProperties* properties;

/**
 * A unique identifier
 */
@property (nonnull) NSString* uuid;

#pragma mark Selection API

/**
 * Returns YES if given quality is selected.
 */
- (BOOL)isQualitySelected:(nonnull CLQuality*)quality;

/**
 * Returns the number of selected qualities.
 */
- (NSUInteger)numberOfSelectedQualities;

/**
 * Select a quality (within the set of qualities for the represented movie).
 */
- (void)selectQuality:(nonnull CLQuality*)quality;

/**
 * Select ALL qualities;
 */
- (void)selectAllQualities;

/**
 * Deselect a quality (within the set of qualities for the represented movie).
 */
- (void)deselectQuality:(nonnull CLQuality*)quality;

/**
 * Deselect ALL selected qualities;
 */
- (void)deselectAllQualities;

/**
 * The size of the selected qualities (if known, otherwise CLDownloadSizeUnknown).
 */
@property (readonly) CLDownloadSize selectedSize;

/**
 * Returns YES if given quality is downloaded.
 */
- (BOOL)isQualityDownloaded:(nonnull CLQuality*)quality;

/**
 * Returns the number of downloaded qualities.
 */
- (NSUInteger)numberOfDownloadedQualities;

/**
 * Remove file(s) on disk for downloaded quality.
 */
- (void)removeDownloadedQuality:(nonnull CLQuality*)quality;

/**
 * Remove file(s) on disk for ALL downloaded qualities.
 */
- (void)removeAllDownloadedQualities;

/**
 * The size of the downloaded qualities (if known, otherwise CLDownloadSizeUnknown).
 */
@property (readonly) int64_t downloadedSize;

#pragma mark Quality Information APIs

/**
 * A list of the currently selected qualities.
 */
@property (nullable, readonly) NSArray<CLQuality*>* selectedQualities;

/**
 * A list of the currently downloaded qualities.
 */
@property (nullable, readonly) NSArray<CLQuality*>* downloadedQualities;

/**
 * Get expected number of bytes to download for given quality (or CLDownloadSizeUnknown if not
 * known).
 */
- (CLDownloadSize)expectedBytesForQuality:(nonnull CLQuality*)quality;

/**
 * Get number of bytes downloaded for given quality.
 */
- (int64_t)downloadedBytesForQuality:(nonnull CLQuality*)quality;

/**
 * Get progress in 0.0-1.0 scaled percentage for given quality (or CLDownloadStatsProgressUnknown
 * if not known).
 */
- (CLDownloadProgress)progressForQuality:(nonnull CLQuality*)quality;

#pragma mark <CLDownloadStats>

/**
 * Size value in bytes, either precise or estimated (see CLDownloadSize).
 */
@property (readonly) CLDownloadSize expectedBytes;

/**
 * Number of bytes downloaded.
 */
@property (readonly) int64_t downloadedBytes;

/**
 * Progress in 0.0-1.0 scaled percentage, either precise or estimated (see CLDownloadProgress).
 */
@property (readonly) CLDownloadProgress progress;

@end
