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

#import "CLMovieDownloadSet.h"
#import "CLRangedURL.h"
#import "CLResourceDownloadInfo.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
