/// <summary>
 /// Returns a new <see cref="ILocator"/> instance.
 /// </summary>
 /// <param name="context">The <see cref="CloudMediaContext"/> instance.</param>
 /// <param name="asset">The <see cref="IAsset"/> instance for the new <see cref="ILocator"/>.</param>
 /// <param name="locatorType">The <see cref="LocatorType"/>.</param>
 /// <param name="permissions">The <see cref="AccessPermissions"/> of the <see cref="IAccessPolicy"/> associated with the new <see cref="ILocator"/>.</param>
 /// <param name="duration">The duration of the <see cref="IAccessPolicy"/> associated with the new <see cref="ILocator"/>.</param>
 /// <param name="startTime">The start time of the new <see cref="ILocator"/>.</param>
 /// <returns>A a new <see cref="ILocator"/> instance.</returns>
 public static ILocator CreateLocator(this CloudMediaContext context, IAsset asset, LocatorType locatorType, AccessPermissions permissions, TimeSpan duration, DateTime?startTime)
 {
     using (Task <ILocator> task = context.CreateLocatorAsync(asset, locatorType, permissions, duration, startTime))
     {
         return(task.Result);
     }
 }
        /// <summary>
        /// Returns a <see cref="System.Threading.Tasks.Task"/> instance to download all the asset files in the <paramref name="asset"/> to the <paramref name="folderPath"/>.
        /// </summary>
        /// <param name="context">The <see cref="CloudMediaContext"/> instance.</param>
        /// <param name="asset">The <see cref="IAsset"/> instance where to download the asset files.</param>
        /// <param name="folderPath">The path to the folder where to download the asset files in the <paramref name="asset"/>.</param>
        /// <param name="downloadProgressChangedCallback">A callback to report download progress for each asset file in the <paramref name="asset"/>.</param>
        /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> instance used for cancellation.</param>
        /// <returns>A <see cref="System.Threading.Tasks.Task"/> instance to download all the asset files in the <paramref name="asset"/>.</returns>
        public static async Task DownloadAssetFilesToFolderAsync(this CloudMediaContext context, IAsset asset, string folderPath, Action <IAssetFile, DownloadProgressChangedEventArgs> downloadProgressChangedCallback, CancellationToken cancellationToken)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context", "The context cannot be null.");
            }

            if (asset == null)
            {
                throw new ArgumentNullException("asset", "The asset cannot be null.");
            }

            if (!Directory.Exists(folderPath))
            {
                throw new ArgumentException(
                          string.Format(CultureInfo.InvariantCulture, "The folder '{0}' does not exist.", folderPath),
                          "folderPath");
            }

            ILocator sasLocator = await context.CreateLocatorAsync(asset, LocatorType.Sas, AccessPermissions.Read, DefaultAccessPolicyDuration);

            EventHandler <DownloadProgressChangedEventArgs> downloadProgressChangedHandler =
                (s, e) =>
            {
                IAssetFile assetFile = (IAssetFile)s;
                DownloadProgressChangedEventArgs eventArgs = e;

                if (downloadProgressChangedCallback != null)
                {
                    downloadProgressChangedCallback(assetFile, eventArgs);
                }
            };

            List <Task>       downloadTasks = new List <Task>();
            List <IAssetFile> assetFiles    = asset.AssetFiles.ToList();

            foreach (IAssetFile assetFile in assetFiles)
            {
                string             localDownloadPath  = Path.Combine(folderPath, assetFile.Name);
                BlobTransferClient blobTransferClient = new BlobTransferClient
                {
                    NumberOfConcurrentTransfers = context.NumberOfConcurrentTransfers,
                    ParallelTransferThreadCount = context.ParallelTransferThreadCount
                };

                assetFile.DownloadProgressChanged += downloadProgressChangedHandler;

                downloadTasks.Add(
                    assetFile.DownloadAsync(Path.GetFullPath(localDownloadPath), blobTransferClient, sasLocator, cancellationToken));
            }

            await Task.WhenAll(downloadTasks);

            await sasLocator.DeleteAsync();

            assetFiles.ForEach(af => af.DownloadProgressChanged -= downloadProgressChangedHandler);
        }
        /// <summary>
        /// Returns a <see cref="System.Threading.Tasks.Task&lt;IAsset&gt;"/> instance for a new <see cref="IAsset"/> with the files in <paramref name="folderPath"/>.
        /// </summary>
        /// <param name="context">The <see cref="CloudMediaContext"/> instance.</param>
        /// <param name="folderPath">The path to the folder with the files to upload to the new <see cref="IAsset"/>.</param>
        /// <param name="storageAccountName">The name of the Storage Account where to store the new <see cref="IAsset"/>.</param>
        /// <param name="options">The <see cref="AssetCreationOptions"/>.</param>
        /// <param name="uploadProgressChangedCallback">A callback to report upload progress of the files.</param>
        /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> instance used for cancellation.</param>
        /// <returns>A <see cref="System.Threading.Tasks.Task&lt;IAsset&gt;"/> instance for a new <see cref="IAsset"/> with the files in <paramref name="folderPath"/>.</returns>
        public static async Task <IAsset> CreateAssetFromFolderAsync(this CloudMediaContext context, string folderPath, string storageAccountName, AssetCreationOptions options, Action <IAssetFile, UploadProgressChangedEventArgs> uploadProgressChangedCallback, CancellationToken cancellationToken)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context", "The context cannot be null.");
            }

            IEnumerable <string> filePaths = Directory.EnumerateFiles(folderPath);

            if (!filePaths.Any())
            {
                throw new FileNotFoundException(
                          string.Format(CultureInfo.InvariantCulture, "No files in directory, check the folder path: '{0}'", folderPath));
            }

            if (string.IsNullOrWhiteSpace(storageAccountName))
            {
                storageAccountName = context.DefaultStorageAccount.Name;
            }

            string assetName = Path.GetFileName(Path.GetFullPath(folderPath.TrimEnd('\\')));
            IAsset asset     = await context.Assets.CreateAsync(assetName, storageAccountName, options, cancellationToken);

            ILocator sasLocator = await context.CreateLocatorAsync(asset, LocatorType.Sas, AccessPermissions.Write | AccessPermissions.List, DefaultAccessPolicyDuration);

            EventHandler <UploadProgressChangedEventArgs> uploadProgressChangedHandler =
                (s, e) =>
            {
                IAssetFile assetFile = (IAssetFile)s;
                UploadProgressChangedEventArgs eventArgs = e;

                if (uploadProgressChangedCallback != null)
                {
                    uploadProgressChangedCallback(assetFile, eventArgs);
                }
            };

            IList <Task> uploadTasks = new List <Task>();

            foreach (string filePath in filePaths)
            {
                uploadTasks.Add(
                    context.CreateAssetFileFromLocalFileAsync(asset, filePath, sasLocator, uploadProgressChangedHandler, cancellationToken));
            }

            await Task.WhenAll(uploadTasks);

            await sasLocator.DeleteAsync();

            return(asset);
        }
        /// <summary>
        /// Returns a <see cref="System.Threading.Tasks.Task&lt;IAsset&gt;"/> instance for a new <see cref="IAsset"/> with the file in <paramref name="filePath"/>.
        /// </summary>
        /// <param name="context">The <see cref="CloudMediaContext"/> instance.</param>
        /// <param name="filePath">The path to the file to upload to the new <see cref="IAsset"/>.</param>
        /// <param name="storageAccountName">The name of the Storage Account where to store the new <see cref="IAsset"/>.</param>
        /// <param name="options">The <see cref="AssetCreationOptions"/>.</param>
        /// <param name="uploadProgressChangedCallback">A callback to report the upload progress of the file.</param>
        /// <param name="cancellationToken">The <see cref="System.Threading.CancellationToken"/> instance used for cancellation.</param>
        /// <returns>A <see cref="System.Threading.Tasks.Task&lt;IAsset&gt;"/> instance for a new <see cref="IAsset"/> with the file in <paramref name="filePath"/>.</returns>
        public static async Task <IAsset> CreateAssetFromFileAsync(this CloudMediaContext context, string filePath, string storageAccountName, AssetCreationOptions options, Action <IAssetFile, UploadProgressChangedEventArgs> uploadProgressChangedCallback, CancellationToken cancellationToken)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context", "The context cannot be null.");
            }

            string assetName = Path.GetFileName(filePath);

            if (string.IsNullOrWhiteSpace(storageAccountName))
            {
                storageAccountName = context.DefaultStorageAccount.Name;
            }

            IAsset asset = await context.Assets.CreateAsync(assetName, storageAccountName, options, cancellationToken);

            ILocator sasLocator = await context.CreateLocatorAsync(asset, LocatorType.Sas, AccessPermissions.Write | AccessPermissions.List, DefaultAccessPolicyDuration);

            EventHandler <UploadProgressChangedEventArgs> uploadProgressChangedHandler =
                (s, e) =>
            {
                IAssetFile assetFile = (IAssetFile)s;
                UploadProgressChangedEventArgs eventArgs = e;

                if (uploadProgressChangedCallback != null)
                {
                    uploadProgressChangedCallback(assetFile, eventArgs);
                }
            };

            await context.CreateAssetFileFromLocalFileAsync(asset, filePath, sasLocator, uploadProgressChangedHandler, cancellationToken);

            await sasLocator.DeleteAsync();

            return(asset);
        }
 /// <summary>
 /// Returns a <see cref="System.Threading.Tasks.Task&lt;ILocator&gt;"/> instance for new <see cref="ILocator"/>.
 /// </summary>
 /// <param name="context">The <see cref="CloudMediaContext"/> instance.</param>
 /// <param name="asset">The <see cref="IAsset"/> instance for the new <see cref="ILocator"/>.</param>
 /// <param name="locatorType">The <see cref="LocatorType"/>.</param>
 /// <param name="permissions">The <see cref="AccessPermissions"/> of the <see cref="IAccessPolicy"/> associated with the new <see cref="ILocator"/>.</param>
 /// <param name="duration">The duration of the <see cref="IAccessPolicy"/> associated with the new <see cref="ILocator"/>.</param>
 /// <returns>A <see cref="System.Threading.Tasks.Task&lt;ILocator&gt;"/> instance for new <see cref="ILocator"/>.</returns>
 public static Task <ILocator> CreateLocatorAsync(this CloudMediaContext context, IAsset asset, LocatorType locatorType, AccessPermissions permissions, TimeSpan duration)
 {
     return(context.CreateLocatorAsync(asset, locatorType, permissions, duration, null));
 }