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

#import "CLResourceDownloadInfo.h"
#import "CLMovieDownloadSet.h"
#import "CLRangedURL.h"

@interface CLQualityDownloadInfo <CLDownloadStats> : NSObject

#pragma mark Properties

/**
 * The resources represented by this quality info.
 */
@property (nonnull, nonatomic, readonly) NSArray<CLResourceDownloadInfo*>* resources;

/**
 * The destination path for the downloads.
 */
@property (nonnull, nonatomic, readonly) NSString* downloadPath;

/**
 * The downloading quality.
 */
@property (nonnull, nonatomic, readonly) CLQuality* quality;

/**
 * The parent set.
 */
@property (nonnull, nonatomic, readonly) CLMovieDownloadSet* set;

/**
 * Additional headers to include in download requests.
 */
@property (nullable, nonatomic) NSDictionary<NSString*, NSString*>* additionalHeaders;

/**
 * Number of parallell downloads to initiate.
 */
@property (nonatomic) NSUInteger parallellDownloads;

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

/**
 * Indicates if download is complete (does not indicate failure or success).
 */
@property (nonatomic, readonly) BOOL completed;

/**
 * Indicates if download failed.
 */
@property (nonatomic, readonly) BOOL failed;

/**
 * If the download has failed this property returns the error, otherwise `nil` is returned.
 */
@property (nullable, nonatomic, readonly) NSError* error;

#pragma mark Download APIs

/**
 * Initiate downloads.
 *
 * @return YES if initiation was successful, NO if no resource download could be initiated.
 */
- (BOOL)download;

/**
 * Re-attach a download task that is in progress to a resource.
 *
 * @return YES if attachment was successful, NO if not.
 */
- (BOOL)reattachResource:(nonnull CLResourceId*)resourceId toTask:(nonnull NSURLSessionDownloadTask*)task;

/**
 * Pause download.
 *
 * @return YES if pause was successful, NO if quality was not running.
 */
- (BOOL)pause;

/**
 * Resume download.
 *
 * @return YES if resume was successful, NO if quality was not paused.
 */
- (BOOL)resume;

/**
 * Cancel download.
 *
 * @return YES if cancellation was successful, NO if quality was not active.
 */
- (BOOL)cancel;

/**
 * Clear any error state for the download.
 *
 * @return YES if an error was cleared, NO if not.
 */
- (BOOL)clear;

/**
 * Reset download stats.
 */
- (void)reset;

/**
 * Complete quality resource with error (which may be `nil` if successful).
 *
 * @return YES if quality was completed, NO if there are still pending resources.
 */
- (BOOL)resource:(nonnull CLResourceDownloadInfo*)resource completeWithError:(nullable NSError*)error;

/**
 * Complete quality resource with preloaded size.
 */
- (void)resource:(nonnull CLResourceDownloadInfo*)resource completeWithBytesPreloaded:(int64_t)preloaded;

/**
 * Update downloaded and expected bytes for quality resource.
 */
- (void)resource:(nonnull CLResourceDownloadInfo*)resource bytesDownloaded:(int64_t)downloaded bytesExpected:(int64_t)expected;

#pragma mark <CLDownloadStats>

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

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

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

#pragma mark Initialization & Creation

/**
 * Initialize a CLQualityDownloadInfo instance.
 */
- (nullable instancetype)initWithBaseURL:(nonnull NSString*)baseURL
                            downloadPath:(nonnull NSString*)destination
                                 quality:(nonnull CLQuality*)quality
                                    set:(nonnull CLMovieDownloadSet*)set
                          andController:(nonnull id<CLSessionController>)controller;

/**
 * Allocate & initialize a CLQualityDownloadInfo instance.
 */
+ (nullable instancetype)infoWithBaseURL:(nonnull NSString*)baseURL
                            downloadPath:(nonnull NSString*)destination
                                 quality:(nonnull CLQuality*)quality
                                    set:(nonnull CLMovieDownloadSet*)set
                          andController:(nonnull id<CLSessionController>)controller;

@end
