public Task UpdateStatsValueDocument(XboxLiveUser user, StatsValueDocument statValuePostDocument)
        {
            string pathAndQuery = PathAndQueryStatSubpath(
                user.XboxUserId,
                this.config.PrimaryServiceConfigId,
                false
                );

            XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(HttpMethod.Post, this.statsWriteEndpoint, pathAndQuery);
            var svdModel            = new Models.StatsValueDocumentModel()
            {
                Revision  = ++statValuePostDocument.Revision,
                Timestamp = DateTime.Now,
                Stats     = new Models.Stats()
                {
                    Title = new Dictionary <string, Models.Stat>()
                }
            };

            svdModel.Stats.Title = statValuePostDocument.Stats.ToDictionary(
                stat => stat.Key,
                stat => new Models.Stat()
            {
                Value = stat.Value.Value
            });

            req.RequestBody   = JsonConvert.SerializeObject(svdModel, serializerSettings);
            req.XboxLiveAPI   = XboxLiveAPIName.UpdateStatsValueDocument;
            req.CallerContext = "StatsManager";
            req.RetryAllowed  = false;
            return(req.GetResponseWithAuth(user));
        }
        internal MockStatsManager()
        {
            this.LocalUsers = new List <XboxLiveUser>();
            Dictionary <string, Models.Stat> statMap = new Dictionary <string, Models.Stat>
            {
                {
                    "DefaultNum", new Models.Stat()
                    {
                        Value = 1.5f
                    }
                },
                {
                    "DefaultString", new Models.Stat()
                    {
                        Value = "stringVal"
                    }
                },
                {
                    "Default", new Models.Stat()
                    {
                        Value = 1
                    }
                }
            };

            this.statValueDocument = new StatsValueDocument(statMap);

            this.statEventList = new List <StatEvent>();
        }
        internal void MergeStatDocument(StatsValueDocument mergeStatDocument)
        {
            switch (this.State)
            {
            case StatValueDocumentState.NotLoaded:
                this.Revision = mergeStatDocument.Revision;
                this.Stats    = mergeStatDocument.Stats;
                break;

            // for offline the stat values local override any service values
            // only add any undefined stats into our list
            case StatValueDocumentState.OfflineNotLoaded:
            case StatValueDocumentState.OfflineLoaded:
                foreach (var stat in mergeStatDocument.Stats)
                {
                    if (this.Stats.ContainsKey(stat.Key))
                    {
                        this.Stats.Add(stat.Key, stat.Value);
                    }
                }
                break;

            case StatValueDocumentState.Loaded:
                throw new Exception("MergeStatDocument called with state: StatValueDocumentState.Loaded");

            default:
                break;
            }

            this.State = StatValueDocumentState.Loaded;
        }
        private void FlushToService(XboxLiveUser user, StatsValueDocument document)
        {
            if (user == null)
            {
                // User could have been removed.
                return;
            }

            document.ClearDirtyState();
            if (document.State != StatsValueDocument.StatValueDocumentState.Loaded)   // if not loaded, try and get the SVD from the service
            {
                this.statsService.GetStatsValueDocument(user).ContinueWith((continuationTask) =>
                {
                    lock (this.userDocumentMap)
                    {
                        if (this.userDocumentMap.ContainsKey(user.XboxUserId))
                        {
                            if (!continuationTask.IsFaulted)
                            {
                                var updatedSvd = continuationTask.Result;
                                this.userDocumentMap[user.XboxUserId].MergeStatDocument(updatedSvd);
                                UpdateStatsValueDocument(user, updatedSvd);
                            }
                            else
                            {
                                UpdateStatsValueDocument(user, this.userDocumentMap[user.XboxUserId]);
                            }
                        }
                        else
                        {
                            // log error: User not found in flush_to_service lambda
                        }
                    }
                });
            }
            else
            {
                UpdateStatsValueDocument(user, document);
            }
        }
        private void UpdateStatsValueDocument(XboxLiveUser user, StatsValueDocument document)
        {
            if (user == null)
            {
                // User could have been removed.
                return;
            }

            this.statsService.UpdateStatsValueDocument(user, document).ContinueWith((continuationTask) =>
            {
                lock (this.userDocumentMap)
                {
                    if (this.userDocumentMap.ContainsKey(user.XboxUserId))
                    {
                        if (continuationTask.IsFaulted)
                        {
                            if (this.ShouldWriteOffline(continuationTask.Exception))
                            {
                                var userSvd = this.userDocumentMap[user.XboxUserId];
                                if (userSvd.State == StatsValueDocument.StatValueDocumentState.Loaded)
                                {
                                    userSvd.State = StatsValueDocument.StatValueDocumentState.OfflineLoaded;
                                }

                                this.WriteOffline(user, userSvd);
                            }
                            else
                            {
                                // log error: Stats manager could not write stats value document
                            }
                        }

                        this.AddEvent(new StatEvent(StatEventType.StatUpdateComplete, user, continuationTask.Exception, new StatEventArgs()));
                    }
                }
            });
        }
        public Task <StatsValueDocument> GetStatsValueDocument(XboxLiveUser user)
        {
            string pathAndQuery = PathAndQueryStatSubpath(
                user.XboxUserId,
                this.config.PrimaryServiceConfigId,
                false
                );

            XboxLiveHttpRequest req = XboxLiveHttpRequest.Create(HttpMethod.Get, this.statsReadEndpoint, pathAndQuery);

            req.XboxLiveAPI   = XboxLiveAPIName.GetStatsValueDocument;
            req.CallerContext = "StatsManager";
            return(req.GetResponseWithAuth(user).ContinueWith(task =>
            {
                XboxLiveHttpResponse response = task.Result;
                var svdModel = JsonConvert.DeserializeObject <Models.StatsValueDocumentModel>(response.ResponseBodyString);
                var svd = new StatsValueDocument(svdModel.Stats.Title, svdModel.Revision)
                {
                    State = StatsValueDocument.StatValueDocumentState.Loaded,
                    User = user
                };
                return svd;
            }));
        }
 private void WriteOffline(XboxLiveUser user, StatsValueDocument document)
 {
     // TODO: implement
 }