public Quota GetQuota( )
        {
            try
            {
                GraphServiceClient graphServiceClient;
                while (!GraphServiceClients.TryDequeue(out graphServiceClient))
                {
                    Thread.Sleep(1);
                }

                Drive driveInfo = graphServiceClient.
                                  Me.Drive.Request( ).
                                  WithMaxRetry(5).
                                  GetAsync( ).
                                  Result;

                GraphServiceClients.Enqueue(graphServiceClient);

                Quota quota = new Quota
                {
                    TotalQuota =
                        driveInfo ? .Quota ? .Total ?? long.MaxValue,
                    RemainingQuota = driveInfo ? .Quota ? .Remaining ?? 0,
                };

                return(quota);
            }
            catch (Exception e)
            {
                Logger.LogError(e, "Update quota failed.");
                throw;
            }
        }
        public async Task Login( )
        {
            int parallelOperationLimit = Math.Max(
                Program.
                Program.Current.Setting.
                ParallelOperationLimit,
                1);

            Task [] tasks = new Task[parallelOperationLimit];

            for (int i = 0; i < parallelOperationLimit; i++)
            {
                tasks [i] = CreateServiceClient( );
            }

            Task.WaitAll(tasks);

            GraphServiceClient graphServiceClient;

            while (!GraphServiceClients.TryDequeue(out graphServiceClient))
            {
                Thread.Sleep(1);
            }

            User me = await graphServiceClient.Me.Request( ).GetAsync( );

            ;

            GraphServiceClients.Enqueue(graphServiceClient);


            Logger.LogInformation("Login as {0}", me.UserPrincipalName);
        }
        public async Task CreateServiceClient( )
        {
            HttpClientFactory httpClientFactory = new HttpClientFactory( );

            IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder.
                                                               Create(Setting.ClientId).
                                                               WithTenantId(Setting.TenantId).
                                                               WithHttpClientFactory(
                httpClientFactory).
                                                               Build( );

            string [] scopes = { "User.Read", "Sites.ReadWrite.All" };

            UsernamePasswordProvider authProvider =
                new UsernamePasswordProvider(publicClientApplication, scopes);

            HttpProvider httpProvider = new HttpProvider(
                Program.
                Program.Current.
                HttpClientHandler,
                false);                                                                                                     // Setting disposeHandler to true does not affect the behavior

            GraphServiceClient graphServiceClient =
                new GraphServiceClient(authProvider, httpProvider);

            User me = await graphServiceClient.
                      Me.Request( ).
                      WithUsernamePassword(
                GraphCredential.UserName,
                GraphCredential.SecurePassword).
                      GetAsync( );

            GraphServiceClients.Enqueue(graphServiceClient);
        }
        public async Task UploadFile(string fileName, byte [] data)
        {
            fileName = $"{Setting . BlockDirectory}\\{fileName}";

            MemoryStream dataStream = new MemoryStream(data);

            GraphServiceClient graphServiceClient;

            while (!GraphServiceClients.TryDequeue(out graphServiceClient))
            {
                Thread.Sleep(1);
            }

            await graphServiceClient.Me.Drive.Root.ItemWithPath(fileName).
            Content.Request( ).
            WithMaxRetry(5).
            PutAsync <DriveItem> (dataStream);

            GraphServiceClients.Enqueue(graphServiceClient);
        }
        public async Task <byte []> DownloadFile(string fileName)
        {
            fileName = $"{Setting . BlockDirectory}\\{fileName}";

            Stream remoteFile = null;

            GraphServiceClient graphServiceClient;

            while (!GraphServiceClients.TryDequeue(out graphServiceClient))
            {
                Thread.Sleep(1);
            }

            try
            {
                remoteFile = await graphServiceClient.
                             Me.Drive.Root.ItemWithPath(fileName).
                             Content.Request( ).
                             WithMaxRetry(5).
                             GetAsync( );
            }
            catch (Exception e)
            {
                Logger.LogWarning(e, "Error downloading {0}", fileName);
            }

            GraphServiceClients.Enqueue(graphServiceClient);

            if (remoteFile != null)
            {
                byte [] blockData = new byte[remoteFile.Length];

                await remoteFile.ReadAsync(blockData);

                return(blockData);
            }
            else
            {
                throw new Exception( );
            }
        }