StorageClientOptions
Defines the client configuration options for connecting to Azure
            Storage.
            
                using Azure.Core;
using Azure.Core.Pipeline;
using Azure.Storage.Common;
using Azure.Storage.Shared;
using System;
namespace Azure.Storage
{
    internal static class StorageClientOptions
    {
        private const string StorageScope = "https://storage.azure.com/.default";
        public static void Initialize(this ClientOptions options)
        {
            options.Retry.MaxRetries = 5;
        }
        public static HttpPipelinePolicy (this StorageSharedKeyCredential credential)
        {
            if (credential == null)
                throw Errors.ArgumentNull("credential");
            return new StorageSharedKeyPipelinePolicy(credential);
        }
        public static HttpPipelinePolicy AsPolicy<TUriBuilder>(this AzureSasCredential credential, Uri resourceUri)
        {
            Argument.AssertNotNull(resourceUri, "resourceUri");
            Argument.AssertNotNull(credential, "credential");
            if (resourceUri.GetQueryParameters().ContainsKey("sig"))
                throw Errors.SasCredentialRequiresUriWithoutSas<TUriBuilder>(resourceUri);
            return new AzureSasCredentialSynchronousPolicy(credential);
        }
        public static HttpPipelinePolicy AsPolicy(this TokenCredential credential, string scope, ClientOptions options)
        {
            if (credential == null)
                throw Errors.ArgumentNull("credential");
            return new StorageBearerTokenChallengeAuthorizationPolicy(credential, scope ?? "https://storage.azure.com/.default", (options as ISupportsTenantIdChallenges)?.EnableTenantDiscovery ?? false);
        }
        public static HttpPipelinePolicy GetAuthenticationPolicy(object credentials = null, string scope = null, ClientOptions options = null)
        {
            if (credentials is SharedAccessSignatureCredentials || credentials == null)
                return null;
            StorageSharedKeyCredential val = credentials as StorageSharedKeyCredential;
            if (val != null)
                return val.AsPolicy();
            TokenCredential tokenCredential = credentials as TokenCredential;
            if (tokenCredential != null)
                return tokenCredential.AsPolicy(scope, options);
            AzureSasCredential azureSasCredential = credentials as AzureSasCredential;
            if (azureSasCredential != null)
                return new AzureSasCredentialSynchronousPolicy(azureSasCredential);
            throw Errors.InvalidCredentials(credentials.GetType().FullName);
        }
        public static HttpPipeline Build(this ClientOptions options, HttpPipelinePolicy authentication = null, Uri geoRedundantSecondaryStorageUri = null, Request100ContinueOptions expectContinue = null)
        {
            StorageResponseClassifier storageResponseClassifier = new StorageResponseClassifier();
            HttpPipelineOptions httpPipelineOptions = new HttpPipelineOptions(options) {
                PerCallPolicies = {
                    (HttpPipelinePolicy)StorageServerTimeoutPolicy.Shared
                },
                PerRetryPolicies = {
                    (HttpPipelinePolicy)StorageTelemetryPolicy.Shared
                },
                ResponseClassifier = storageResponseClassifier,
                RequestFailedDetailsParser = new StorageRequestFailedDetailsParser()
            };
            if (geoRedundantSecondaryStorageUri != (Uri)null) {
                httpPipelineOptions.PerRetryPolicies.Add(new GeoRedundantReadPolicy(geoRedundantSecondaryStorageUri));
                storageResponseClassifier.SecondaryStorageUri = geoRedundantSecondaryStorageUri;
            }
            if (expectContinue != null) {
                Request100ContinueMode mode = expectContinue.get_Mode();
                switch ((int)mode) {
                case 0:
                    httpPipelineOptions.PerCallPolicies.Add(new ExpectContinueOnThrottlePolicy {
                        ThrottleInterval = expectContinue.get_AutoInterval(),
                        ContentLengthThreshold = expectContinue.get_ContentLengthThreshold().GetValueOrDefault()
                    });
                    break;
                case 1:
                    httpPipelineOptions.PerCallPolicies.Add(new ExpectContinuePolicy {
                        ContentLengthThreshold = expectContinue.get_ContentLengthThreshold().GetValueOrDefault()
                    });
                    break;
                }
            } else
                httpPipelineOptions.PerCallPolicies.Add(new ExpectContinueOnThrottlePolicy {
                    ThrottleInterval = TimeSpan.FromMinutes(1)
                });
            httpPipelineOptions.PerRetryPolicies.Add(new StorageRequestValidationPipelinePolicy());
            httpPipelineOptions.PerRetryPolicies.Add(authentication);
            return HttpPipelineBuilder.Build(httpPipelineOptions);
        }
        public static HttpPipeline Build(this ClientOptions options, object credentials, Uri geoRedundantSecondaryStorageUri = null, Request100ContinueOptions expectContinue = null)
        {
            return options.Build(GetAuthenticationPolicy(credentials, null, null), geoRedundantSecondaryStorageUri, expectContinue);
        }
    }
}