//
        // GET: /UserProfile/
        public async Task<ActionResult> Index(string authError)
        {
            UserProfile profile = null;
            AuthenticationContext authContext = null;
            AuthenticationResult result = null;
            string userObjectID = ClaimsPrincipal.Current.FindFirst("http://schemas.xmlsoap.org/ws/2005/05/identity/claims/nameidentifier").Value;

            try
            {
                ClientCredential credential = new ClientCredential(Startup.clientId, Startup.appKey);
                authContext = new AuthenticationContext(Startup.Authority, new TokenDbCache(userObjectID));

                if (authError != null)
                {
                    Uri redirectUri = new Uri(Request.Url.GetLeftPart(UriPartial.Authority).ToString() + "/OAuth");
                    string state = GenerateState(userObjectID, Request.Url.ToString());
                    ViewBag.AuthorizationUrl = authContext.GetAuthorizationRequestURL(Startup.graphResourceId, Startup.clientId, redirectUri, UserIdentifier.AnyUser, state == null ? null : "&state=" + state);

                    profile = new UserProfile();
                    profile.DisplayName = " ";
                    profile.GivenName = " ";
                    profile.Surname = " ";
                    ViewBag.ErrorMessage = "UnexpectedError";
                    return View(profile);
                }

                result = authContext.AcquireTokenSilent(Startup.graphResourceId, credential, UserIdentifier.AnyUser);
            }
            catch (AdalException e)
            {
                if (e.ErrorCode == "failed_to_acquire_token_silently") {
                    
                    // The user needs to re-authorize.  Show them a message to that effect.
                    // If the user still has a valid session with Azure AD, they will not be prompted for their credentials.

                    profile = new UserProfile();
                    profile.DisplayName = " ";
                    profile.GivenName = " ";
                    profile.Surname = " ";
                    ViewBag.ErrorMessage = "AuthorizationRequired";
                    authContext = new AuthenticationContext(Startup.Authority);
                    Uri redirectUri = new Uri(Request.Url.GetLeftPart(UriPartial.Authority).ToString() + "/OAuth");

                    string state = GenerateState(userObjectID, Request.Url.ToString());

                    ViewBag.AuthorizationUrl = authContext.GetAuthorizationRequestURL(Startup.graphResourceId, Startup.clientId, redirectUri, UserIdentifier.AnyUser, state == null ? null : "&state=" + state);

                    return View(profile);
                }

                ViewBag.ErrorMessage = "Error while Acquiring Token from Cache.";
                return View("Error");
            
            }

            try 
            {
                //
                // Call the Graph API and retrieve the user's profile.
                //
                string requestUrl = String.Format(
                    CultureInfo.InvariantCulture,
                    Startup.graphUserUrl,
                    HttpUtility.UrlEncode(result.TenantId));
                HttpClient client = new HttpClient();
                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
                request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", result.AccessToken);
                HttpResponseMessage response = await client.SendAsync(request);

                //
                // Return the user's profile in the view.
                //
                if (response.IsSuccessStatusCode)
                {
                    string responseString = await response.Content.ReadAsStringAsync();
                    profile = JsonConvert.DeserializeObject<UserProfile>(responseString);
                    return View(profile);
                }
                else if (response.StatusCode == HttpStatusCode.Unauthorized)
                {
                    //
                    // If the call failed, then drop the current access token and show the user an error indicating they might need to sign-in again.
                    //
                    authContext.TokenCache.Clear();

                    Uri redirectUri = new Uri(Request.Url.GetLeftPart(UriPartial.Authority).ToString() + "/OAuth");
                    string state = GenerateState(userObjectID, Request.Url.ToString());
                    ViewBag.AuthorizationUrl = authContext.GetAuthorizationRequestURL(Startup.graphResourceId, Startup.clientId, redirectUri, UserIdentifier.AnyUser, state == null ? null : "&state=" + state);

                    profile = new UserProfile();
                    profile.DisplayName = " ";
                    profile.GivenName = " ";
                    profile.Surname = " ";
                    ViewBag.ErrorMessage = "UnexpectedError";
                    return View(profile);
                }

                ViewBag.ErrorMessage = "Error Calling Graph API.";
                return View("Error");
            } 
            catch 
            {
                ViewBag.ErrorMessage = "Error Calling Graph API.";
                return View("Error");
            }
        }
        // If you are adapting an application that authenticates Azure AD users using Windows Identity Foundation,
        // you can get the user's Tenant ID from ClaimsPrincipal.Current.  Otherwise, this sample caches the user's
        // Tenant ID when it is obtained during the OAuth authorization flow.
        // private const string TenantIdClaimType = "http://schemas.microsoft.com/identity/claims/tenantid";

        //
        // GET: /UserProfile/
        public async Task<ActionResult> Index()
        {
            //
            // Retrieve the user's name, tenantID, and access token since they are parameters used to query the Graph API.
            //
            UserProfile profile = null;
            string accessToken = null;
            
            // If you authenticated an Azure AD user using Windows Identity Foundation, you can use ClaimsPrincipal.Current to get the user's Tenant ID.
            // string tenantId = ClaimsPrincipal.Current.FindFirst(TenantIdClaimType).Value;
            string tenantId = (string)OAuthController.GetFromCache("TenantId");

            if (tenantId != null)
            {
                accessToken = OAuthController.GetAccessTokenFromCacheOrRefreshToken(tenantId, graphResourceId);
            }

            //
            // If the user doesn't have an access token, they need to re-authorize.
            //
            if (accessToken == null)
            {
                //
                // The user needs to re-authorize.  Show them a message to that effect.
                // If the user still has a valid session with Azure AD, they will not be prompted for their credentials.
                //

                // Remember where to bring the user back to in the application after the authorization code response is handled.
                OAuthController.SaveInCache("RedirectTo", Request.Url);

                profile = new UserProfile();
                profile.DisplayName = " ";
                profile.GivenName = " ";
                profile.Surname = " ";
                ViewBag.ErrorMessage = "AuthorizationRequired";
                ViewBag.AuthorizationUrl = OAuthController.GetAuthorizationUrl(graphResourceId, this.Request);

                return View(profile);
            }

            //
            // Call the Graph API and retrieve the user's profile.
            //
            string requestUrl = String.Format(
                CultureInfo.InvariantCulture,
                graphUserUrl,
                HttpUtility.UrlEncode(tenantId));
            HttpClient client = new HttpClient();
            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUrl);
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
            HttpResponseMessage response = await client.SendAsync(request);

            //
            // Return the user's profile in the view.
            //
            if (response.IsSuccessStatusCode)
            {
                string responseString = await response.Content.ReadAsStringAsync();
                profile = JsonConvert.DeserializeObject<UserProfile>(responseString);
            }
            else
            {
                //
                // If the call failed, then drop the current access token and show the user an error indicating they might need to sign-in again.
                //
                OAuthController.RemoveAccessTokenFromCache(graphResourceId);

                profile = new UserProfile();
                profile.DisplayName = " ";
                profile.GivenName = " ";
                profile.Surname = " ";
                ViewBag.ErrorMessage = "UnexpectedError";
            }

            return View(profile);
        }