public IQueryable<PostModel> GetAllPosts()
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new MyForumContext();

                var models =
                    context.Posts
                    .ToList()
                    .Select(post => new PostModel()
                    {
                        Contetn = post.Content,
                        PostDate = post.PostDate,
                        PostedBy = post.User.Nickname,
                        Rating = string.Format("{0:0.00}/5", post.Votes.Average(ps => ps.Value))
                    }).OrderByDescending(ps => ps.PostDate);

                //    (from post in context.Posts
                //    select new PostModel()
                //    {
                //        Contetn = post.Content,
                //        PostDate = post.PostDate,
                //        PostedBy = post.User.Nickname,
                //        Rating = (post.Votes.Average(ps => ps.Value).ToString())
                //    }).OrderByDescending(ps => ps.PostDate).ToList();

                return models.AsQueryable();

            });

            return responseMsg;
        }
        public HttpResponseMessage PostRegisterUser(UserModel model)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new MyForumContext();
                using (context)
                {
                    this.ValidateUsername(model.Username);
                    this.ValidateNickname(model.Nickname);
                    this.ValidateAuthCode(model.AuthCode);

                    var usernameLower = model.Username.ToLower();
                    var nicknameLower = model.Nickname.ToLower();

                    var user = context.Users
                        .FirstOrDefault(usr => usr.Username == usernameLower ||
                            usr.Nickname == nicknameLower);

                    if (user != null)
                    {
                        throw new InvalidOperationException("User exists");
                    }

                    user = new User()
                    {
                        Username = usernameLower,
                        Nickname = model.Nickname,
                        AuthCode = model.AuthCode,
                    };

                    context.Users.Add(user);
                    context.SaveChanges();

                    user.SessionKey = this.GenerateSessionKey(user.Id);
                    context.SaveChanges();

                    var loggedModel = new LoggedUserModel()
                    {
                        Nickname = user.Nickname,
                        SessionKey = user.SessionKey
                    };

                    var response = this.Request.CreateResponse(
                        HttpStatusCode.Created, loggedModel);

                    return response;
                }
            });

            return responseMsg;
        }
        public HttpResponseMessage PostVote(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey, int postId,
            [FromBody]VoteModel model)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new MyForumContext();

                using (context)
                {
                    var user = context.Users.Where(ur => ur.SessionKey == sessionKey).FirstOrDefault();

                    if (user == null)
                    {
                        throw new ArgumentException("You are not logged in!");
                    }

                    var post = context.Posts.Where(ps => ps.Id == postId).FirstOrDefault();

                    if (post == null)
                    {
                        throw new InvalidOperationException("Invalid vote post");
                    }

                    var vote = new Vote()
                    {
                        Value = model.Value,
                        User = user,
                        Post = post
                    };

                    context.Votes.Add(vote);
                    context.SaveChanges();
                }

                return this.Request.CreateResponse(HttpStatusCode.Created);
            });

            return responseMsg;
        }
        public IQueryable<ThreadModel> GetAll()
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
                {
                    var context = new MyForumContext();
                    var threadEtities = context.Threads;
                    var models = (
                        from thread in threadEtities
                        select new ThreadModel()
                        {
                            Id = thread.Id,
                            Title = thread.Title,
                            DateCreated = thread.DateCreated,
                            Content = thread.Text,
                            CreatedBy = thread.User.Nickname,
                            Posts = (
                            from post in thread.Posts
                            select new PostModel()
                            {
                                Contetn = post.Content,
                                PostDate = post.PostDate,
                                PostedBy = post.User.Nickname,
                                //Rating = string.Format("{0:0.0}/5", post.Votes.Average(vt => vt.Value).ToString())
                            }
                            ),

                            Categories = (
                                from category in thread.Categories
                                select category.Name)

                        })
                        .OrderByDescending(x => x.DateCreated);

                    return models;
                });

            return responseMsg;
        }
        public IQueryable<PostModel> GetPosts(int threadId)
        {
            var context = new MyForumContext();

            //var postsEntites = context.Threads.FirstOrDefault(x => x.Id == threadId).Posts;


            PostModel[] models = 
            {
                new PostModel() 
                {
                    Contetn = "First",
                    PostDate = DateTime.Now,
                    PostedBy = "John",
                    Rating = "5/5"
                },

                new PostModel() 
                {
                    Contetn = "Second",
                    PostDate = DateTime.Now,
                    PostedBy = "John",
                    Rating = "5/5"
                },
            };

            return models.AsQueryable();
        }
        public HttpResponseMessage PostLoginUser(UserModel model)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
            {
                var context = new MyForumContext();
                using (context)
                {
                    this.ValidateUsername(model.Username);
                    this.ValidateAuthCode(model.AuthCode);

                    var usernameLower = model.Username.ToLower();
                    var nicknameLower = model.Nickname.ToLower();

                    var user = context.Users
                        .FirstOrDefault(
                        usr => usr.Username == usernameLower &&
                            usr.AuthCode == model.AuthCode);

                    if (user == null)
                    {
                        throw new InvalidOperationException("Invalid name or password");
                    }

                    if (string.IsNullOrWhiteSpace(user.SessionKey))
                    {
                        user.SessionKey = this.GenerateSessionKey(user.Id);
                        context.SaveChanges();
                    }

                    var loggedModel = new LoggedUserModel()
                    {
                        Nickname = user.Nickname,
                        SessionKey = user.SessionKey
                    };

                    var response = this.Request.CreateResponse(
                        HttpStatusCode.OK, loggedModel);

                    return response;
                }
            });

            return responseMsg;
        }
        public HttpResponseMessage PutLogoutUser([ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(() =>
                {
                    var context = new MyForumContext();
                    using (context)
                    {
                        var user = context.Users.Where(ur => ur.SessionKey == sessionKey).FirstOrDefault();

                        if (user != null)
                        {
                            user.SessionKey = null;
                            context.SaveChanges();
                        }

                        return new HttpResponseMessage(HttpStatusCode.OK);
                    }
                });

            return responseMsg;
        }