/// <summary>
 /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
 /// </summary>
 /// <param name="disposing">To free managed resources.</param>
 void Dispose(bool disposing)
 {
     if (!disposed)
     {
         if (disposing)
         {
             httpClient.Dispose();
         }
         Auth     = null;
         Token    = null;
         disposed = true;
     }
 }
 /// <summary>
 /// Initializes a new instance of the <see cref="HealthGraphClient"/> class.
 /// </summary>
 /// <param name="auth">The data to perform authorization/authentication flows.</param>
 /// <param name="token">The token that allows the user/application access.</param>
 public HealthGraphClient(HealthGraphAuth auth, HealthGraphToken token)
 {
     Auth       = auth ?? throw new ArgumentNullException(nameof(auth));
     Token      = token ?? throw new ArgumentNullException(nameof(token));
     httpClient = new HttpClient();
 }
        /// <summary>
        /// Handles the authorize/de-authorize flow to access to Health Graph.
        /// </summary>
        /// <param name="uri">The URL redirected from browser.</param>
        /// <returns>The result of authorize/de-authorize flow.</returns>
        /// <exception cref="InvalidOperationException">The <see cref="Auth"/> is null or has invalid values or the status sent does not match with status received.</exception>
        public async Task <HealthGraphAuthResult> HandleAuthorizationAsync(Uri uri)
        {
            EnsureAuth();
            var result = new HealthGraphAuthResult
            {
                Status = HealthGraphAuthStatus.None
            };

            if (uri.AbsolutePath.Equals(Auth.RedirectUri.AbsolutePath, StringComparison.OrdinalIgnoreCase))
            {
                // Parse/Validate QueryString
                var queryValues = QueryHelpers.ParseQuery(uri.Query);
                var code        = queryValues.ContainsKey(QUERY_CODE) ? queryValues[QUERY_CODE].ToString() : null;
                var state       = queryValues.ContainsKey(QUERY_STATE) ? queryValues[QUERY_STATE].ToString() : null;
                if (!string.Equals(Auth.State, state, StringComparison.OrdinalIgnoreCase))
                {
                    throw new InvalidOperationException("The request-response states do not match.");
                }
                // Build parameters to request token
                var tokenParams = new Dictionary <string, string>
                {
                    { QUERY_CLIENT_ID, Auth.ClientId },
                    { QUERY_CLIENT_SECRET, Auth.ClientSecret },
                    { QUERY_CODE, code },
                    { QUERY_GRANT_TYPE, GRANT_TYPE_AUTHORIZATION_CODE },
                    { QUERY_REDIRECT_URI, Auth.RedirectUri.ToString() }
                };
                var request = new HttpRequestMessage(HttpMethod.Post, URL_TOKEN)
                {
                    Content = new FormUrlEncodedContent(tokenParams)
                };
                // Perform request token
                var response = await httpClient.SendAsync(request);

                // Parse/validate token response
                result.StatusCode    = response.StatusCode;
                result.ContentString = await response.Content.ReadAsStringAsync();

                var serializerSettings = new JsonSerializerSettings
                {
                    ContractResolver = new DefaultContractResolver
                    {
                        NamingStrategy = new SnakeCaseNamingStrategy()
                    },
                    NullValueHandling = NullValueHandling.Ignore
                };
                if (response.StatusCode == HttpStatusCode.OK)
                {
                    Token            = JsonConvert.DeserializeObject <HealthGraphToken>(result.ContentString, serializerSettings);
                    result.Status    = HealthGraphAuthStatus.Auhtorized;
                    result.ErrorCode = null;
                }
                else
                {
                    Token         = null;
                    result.Status = HealthGraphAuthStatus.Error;
                    var errorObject = JsonConvert.DeserializeObject <HealthGraphAuthErrorObject>(result.ContentString, serializerSettings);
                    result.ErrorCode = errorObject.Error;
                }
            }
            return(result);
        }