private static async Task<Response<string>> GetResponseAsync(string relativeUriFormat, User user)
        {
            Response<string> response;

            try
            {
                string dob = user.DateOfBirth.ToString("ddMMyyyy", System.Globalization.CultureInfo.InvariantCulture);
                var postContent = new HttpFormUrlEncodedContent(
                                    new KeyValuePair<string, string>[3] {
                                        new KeyValuePair<string, string>("regno", user.RegNo),
                                        new KeyValuePair<string, string>("dob", dob),
                                        new KeyValuePair<string, string>("mobile", user.PhoneNo)
                                    });

                string uriString = BASE_URI_STRING + String.Format(relativeUriFormat, user.Campus);
                HttpResponseMessage httpResponse = await _httpClient.PostAsync(new Uri(uriString), postContent);
                response = await GetRootResponseAsync(httpResponse);
            }
            catch
            {
                response = new Response<string>(StatusCode.NoInternet, null);
            }

            return response.Format();
        }
        internal static async Task CreateNewCalendarAsync(User requester)
        {
            await DeleteCalendarAsync();
            
            AppointmentCalendar calendar = await _store.CreateAppointmentCalendarAsync("Academics Calendar");
            calendar.OtherAppReadAccess = AppointmentCalendarOtherAppReadAccess.SystemOnly;
            calendar.OtherAppWriteAccess = AppointmentCalendarOtherAppWriteAccess.None;
            await calendar.SaveAsync();

            _calendar = calendar;
            CalendarOwner = requester.RegNo;
        }
 public static async Task<Response<string>> TryGetAdvisorDetailsAsync(User user)
 {
     return await GetContentAsync(ADVISOR_STRING_FORMAT, user);
 }
 ///<summary>
 /// Get the academic history as a Json string along with status code for the specified user by sending a Http request.
 /// </summary>
 /// <param name="user">
 /// The user whose data to request.
 /// </param>
 /// <remarks>
 /// Note: This method attempts a login and a single retry upon receiving a SessionTimedOut error.
 /// </remarks>
 /// <returns>
 /// A response containing status code and content. Returns the Json string as the content on success, otherwise the content is null.
 /// </returns>
 public static async Task<Response<string>> TryGetGradesAsync(User user)
 {
     return await GetContentAsync(GRADES_STRING_FORMAT, user);
 }
 /// <summary>
 /// Get the data as a Json string along with status code for the specified user by sending a Http request.
 /// </summary>
 /// <param name="user">
 /// The user whose data to request.
 /// </param>
 /// <remarks>
 /// Note: This method attempts a login and a single retry upon receiving a SessionTimedOut error.
 /// </remarks>
 /// <returns>
 /// A response containing status code and content. Returns the Json string as the content on success, otherwise the content is null.
 /// </returns>
 public static async Task<Response<string>> TryGetDataAsync(User user)
 {
     return await GetContentAsync(REFRESH_STRING_FORMAT, user);
 }
        /// <summary>
        /// Attempts to login the passed user and returns the status of the operation.
        /// </summary>
        /// <remarks>
        /// Note: On encountering an internal error, another attempt is made to login before the method returns.
        /// </remarks>
        /// <param name="user">
        /// The user to login.
        /// </param>
        /// <returns>
        /// Status code indicating result of the login attempt.
        /// </returns>
        public static async Task<StatusCode> TryLoginAsync(User user)
        {
            StatusCode statusCode = StatusCode.UnknownError;
            int i = 1;
            while (i++ <= MAX_ATTEMPTS)
            {
                statusCode = (await GetResponseAsync(LOGIN_STRING_FORMAT, user)).Code;

                if (statusCode == StatusCode.TemporaryError         // If Error parsing the captcha (or)
                    || statusCode == StatusCode.InvalidCredentials) // If the captcha was parsed incorrectly
                    continue;                                       // Then attempt to login again
                else
                    break;
            }
            return statusCode;
        }
        /// <summary>
        /// Returns the content and status of the specified network request. Content is null if request fails.
        /// </summary>
        /// <param name="relUriFormat">
        /// The (relative) uri format string into which user parameters will be introduced.
        /// </param>
        /// <param name="user"></param>
        /// <returns></returns>
        private static async Task<Response<string>> GetContentAsync(string relUriFormat, User user)
        {
            Response<string> response = await GetResponseAsync(relUriFormat, user);

            if (response.Code == StatusCode.SessionTimeout)
            {
                StatusCode loginStatus = await TryLoginAsync(user);
                if (loginStatus == StatusCode.Success)
                    response = await GetResponseAsync(relUriFormat, user);
                else
                    response = new Response<string>(loginStatus, null);
            }

            return response;
        }
        /// <summary>
        /// Resets calendar, clears cache and resets the new semester flag, to enable a direct refresh to new data. Other settings and credentials are retained.
        /// </summary>
        /// <returns>
        /// A status code if reset was successful, otherwise an error code.
        /// </returns>
        public static async Task<StatusCode> RunMaintentanceForUpgradeAsync()
        {
            return await MonitoredTask(async () =>
                {
                    if (CurrentUser == null)
                        return StatusCode.InvalidRequest;

                    PropertyChanged = null;
                    CurrentUser = new User(CurrentUser.RegNo, CurrentUser.DateOfBirth, CurrentUser.Campus, CurrentUser.PhoneNo);
                    try
                    {
#if WINDOWS_PHONE_APP
                        await CalendarManager.CreateNewCalendarAsync(CurrentUser);
#endif
                        StorageFile dataFile = await _roamingFolder.GetFileAsync(DATA_JSON_FILE_NAME);
                        await dataFile.DeleteAsync();
                    }
                    catch (FileNotFoundException)
                    { ; }
                    catch (Exception)
                    {
                        return StatusCode.UnknownError;
                    }
                    AppSettings.IsSemesterUpgradeAvailable = false;
                    return StatusCode.Success;
                });
        }
        /// <summary>
        /// Assigns the current user (and logs in) and saves the credentials to the Locker, if a login with the passed parameters was successful.
        /// </summary>
        /// <remarks>
        /// Note: Any existing credentials in the Locker are overwritten on success.
        /// </remarks>
        /// <returns>
        ///  Returns a specific status code as per the login attempt result.
        /// </returns>
        public static async Task<StatusCode> CreateNewUserAsync(string regNo, DateTimeOffset dateOfBirth, string campus, string phoneNo)
        {
            return await MonitoredTask(async () =>
            {
                User user = new User(regNo, dateOfBirth, campus, phoneNo);
                StatusCode status = await NetworkService.TryLoginAsync(user);

                if (status == StatusCode.Success)
                {
                    try
                    {
                        if(CurrentUser != null)
                        {
#if WINDOWS_PHONE_APP
                            await DeleteSavedUserAsync();
#else
                            DeleteSavedUser();
#endif
                        }

                        PasswordCredential credential = GetStoredCredential();
                        if (credential != null)
                            new PasswordVault().Remove(credential);

                        // Store Credentials in the following format: "VITacademics" - "{regNo}" : "{ddMMyyyy}_{campus}_{phoneNo}"
                        new PasswordVault().Add(
                            new PasswordCredential(RESOURCE_NAME, regNo,
                                    string.Format("{0}_{1}_{2}", dateOfBirth.ToString("ddMMyyyy", CultureInfo.InvariantCulture), campus, phoneNo)));

                        CurrentUser = user;
#if WINDOWS_PHONE_APP
                        await CalendarManager.CreateNewCalendarAsync(CurrentUser);
#endif
                    }
                    catch
                    {
                        status = StatusCode.UnknownError;
                    }
                }
                return status;
            }
            );
        }
        /// <summary>
        /// Checks the Credential Locker and assigns current user if available. 
        /// </summary>
        static UserManager()
        {
            PasswordCredential credential = GetStoredCredential();
            if (credential != null)
            {
                try
                {
                    credential = new PasswordVault().Retrieve(RESOURCE_NAME, credential.UserName);
                    // Parse "password" to retrieve DOB, campus and phoneNo
                    string[] values = credential.Password.Split('_');
                    DateTimeOffset dob = DateTimeOffset.ParseExact(values[0], "ddMMyyyy", CultureInfo.InvariantCulture);
                    string campus = values[1];
                    string phoneNo = values[2];
                    CurrentUser = new User(credential.UserName, dob, campus, phoneNo);
                }
                catch
                {
                    // Corrupt data
#if WINDOWS_PHONE_APP
                    DeleteSavedUserAsync();
#else
                    DeleteSavedUser();
#endif
                }
            }
            else
                CurrentUser = null;
        }