public IQueryable<PostModel> GetAllPosts(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
                {
                    var dbContext = new AcadBlogContext();

                    this.ValidateAndGetUserBySessionKey(dbContext, sessionKey);

                    var postModels = dbContext.Posts.Select(
                        p => new PostModel()
                        {
                            Id = p.Id,
                            Title = p.Title,
                            PostedBy = p.User.Displayname,
                            PostDate = p.PostDate,
                            Text = p.Content,
                            Tags = p.Tags.Select(t => t.Title),
                            Comments = p.Comments.Select(
                                c => new CommentModel()
                                {
                                    Text = c.Content,
                                    CommentedBy = c.User.Displayname,
                                    PostDate = c.DateCreated
                                })
                        });

                    return postModels.OrderByDescending(p => p.PostDate);
                });

            return responseMsg;
        }
        private User ValidateAndGetUserBySessionKey(AcadBlogContext dbContext,
            string sessionKey)
        {
            var user = dbContext.Users.FirstOrDefault(
                u => u.SessionKey == sessionKey);

            if (user == null)
            {
                throw new InvalidOperationException("Incorrect session key.");
            }

            return user;
        }
        public HttpResponseMessage PostRegisterUser(UserModel model)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
            {
                using (var dbContext = new AcadBlogContext())
                {
                    this.ValidateUsername(model.Username);
                    this.ValidateNickname(model.Displayname);
                    this.ValidateAuthCode(model.AuthCode);

                    var usernameAsLowercase = model.Username.ToLower();
                    var nicknameAsLowercase = model.Displayname.ToLower();

                    var existingUser = dbContext.Users.FirstOrDefault(
                        u => u.Username == usernameAsLowercase ||
                            u.Displayname == nicknameAsLowercase);

                    if (existingUser != null)
                    {
                        throw new InvalidOperationException(
                            "User with the same displayname or username already exists.");
                    }

                    var newUser = new User()
                    {
                        Username = usernameAsLowercase,
                        Displayname = model.Displayname,
                        AuthCode = model.AuthCode,
                    };

                    dbContext.Users.Add(newUser);
                    dbContext.SaveChanges();

                    newUser.SessionKey = this.GenerateSessionKey(newUser.Id);
                    dbContext.SaveChanges();

                    var loggedModel = new LoggedUserModel()
                    {
                        Displayname = model.Displayname,
                        SessionKey = newUser.SessionKey
                    };

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

                    return response;
                };
            });

            return responseMsg;
        }
        public HttpResponseMessage PostLoginUser(UserModel model)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
            {
                using (var dbContext = new AcadBlogContext())
                {
                    this.ValidateUsername(model.Username);
                    this.ValidateAuthCode(model.AuthCode);

                    var usernameAsLowercase = model.Username.ToLower();
                    var existingUser = dbContext.Users.FirstOrDefault(
                        u => u.Username == usernameAsLowercase &&
                        u.AuthCode == model.AuthCode);

                    if (existingUser == null)
                    {
                        throw new InvalidOperationException(
                            "Username or password is invalid.");
                    }

                    if (existingUser.SessionKey == null)
                    {
                        existingUser.SessionKey = this.GenerateSessionKey(existingUser.Id);
                        dbContext.SaveChanges();
                    }

                    var loggedModel = new LoggedUserModel()
                    {
                        Displayname = existingUser.Displayname,
                        SessionKey = existingUser.SessionKey
                    };

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

                    return response;
                };
            });

            return responseMsg;
        }
        public IQueryable<TagGetModel> GetAllTags(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
            {
                var dbContext = new AcadBlogContext();
                var user = this.ValidateAndGetUserBySessionKey(dbContext, sessionKey);

                var tagModels = dbContext.Tags.Select(
                    t => new TagGetModel
                    {
                        Id = t.Id,
                        Name = t.Title,
                        Posts = t.Posts.Count
                    });

                return tagModels.OrderByDescending(t => t.Name);
            });

            return responseMsg;
        }
        public HttpResponseMessage PutLogoutUser(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
            {
                using (var dbContext = new AcadBlogContext())
                {
                    this.ValidateSessionKey(sessionKey);

                    var user = dbContext.Users.FirstOrDefault(
                        u => u.SessionKey == sessionKey);

                    if (user == null)
                    {
                        throw new InvalidOperationException("Incorrect session key.");
                    }

                    user.SessionKey = null;
                    dbContext.SaveChanges();

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

                    return response;
                }
            });

            return responseMsg;
        }
 private Post ValidateAndGetPostById(AcadBlogContext dbContext, int postId)
 {
     var post = dbContext.Posts.Find(postId);
     if (post == null)
     {
         throw new ArgumentNullException(String.Format(
             "Post with id {0} does not exist.", postId));
     }
     return post;
 }
        private ICollection<Tag> FindOrCreateTagsByTitle(AcadBlogContext context,
            ICollection<string> tags)
        {
            List<Tag> tagsToReturn = new List<Tag>();
            foreach (var tag in tags)
            {
                var existingTag = context.Tags.FirstOrDefault(t => t.Title == tag);
                if (existingTag != null)
                {
                    tagsToReturn.Add(existingTag);
                }
                else
                {
                    var newTag = new Tag()
                    {
                        Title = tag
                    };

                    tagsToReturn.Add(newTag);
                    context.Tags.Add(newTag);
                    context.SaveChanges();
                }
            }

            return tagsToReturn;
        }
        public HttpResponseMessage PutCommentOnAPost(
            int postId, CommentPostModel model,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
            {
                this.ValidateCommentPostModel(model);

                using (var dbContext = new AcadBlogContext())
                {
                    var user = this.ValidateAndGetUserBySessionKey(dbContext, sessionKey);
                    var post = this.ValidateAndGetPostById(dbContext, postId);

                    var newComment = new Comment()
                    {
                        Content = model.Text,
                        DateCreated = DateTime.Now,
                        User = user,
                        Post = post
                    };

                    dbContext.Comments.Add(newComment);
                    dbContext.SaveChanges();

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

                    return response;
                }
            });

            return responseMsg;
        }
        public HttpResponseMessage PostCreatePost(PostCreateRequestModel model,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerfromOperationAndHandleException(() =>
            {
                this.ValidatePostCreateModel(model);

                using (var dbContext = new AcadBlogContext())
                {
                    var user = this.ValidateAndGetUserBySessionKey(dbContext, sessionKey);

                    Post newPost = new Post
                    {
                        Title = model.Title,
                        Content = model.Text,
                        Tags = this.FindOrCreateTagsByTitle(dbContext, model.Tags),
                        PostDate = DateTime.Now,
                        User = user,
                    };

                    dbContext.Posts.Add(newPost);
                    dbContext.SaveChanges();

                    var responseModel = new PostCreateResponseModel()
                    {
                        Id = newPost.Id,
                        Title = model.Title,
                    };

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

                    return response;
                }
            });

            return responseMsg;
        }