public void DeletePost(BlogContext context, string sessionToken, int postId)
        {
            var user = _authenticationService.GetUserBySessionToken(context, sessionToken);
            var post = context.Posts.SingleOrDefault(p => p.PostId == postId);
            if (post == null)
            {
                throw new NoSuchPostException();
            }

            if (post.UserId != user.UserId)
            {
                throw new NoPermissionsException();
            }

            var commentsToDelete = (from comment in context.Comments
                                    where comment.PostId == postId
                                    select comment).ToList();
            foreach (var comment in commentsToDelete)
            {
                context.Comments.Remove(comment);
            }

            context.Posts.Remove(post);
            context.SaveChanges();
        }
        public User GetUserBySessionToken(BlogContext context, string sessionToken)
        {
            var session = context.Sessions
                .Include("User")
                .SingleOrDefault(s => s.SessionToken == sessionToken);
            if (session == null)
            {
                throw new InvalidSessionException();
            }

            return session.User;
        }
        public PostDTO GetPost(BlogContext context, string sessionToken, int postId)
        {
            _authenticationService.MakeSureSessionTokenIsOk(context, sessionToken);

            var post = context.Posts
                .Include("Comments")
                .SingleOrDefault(p => p.PostId == postId);
            if (post == null)
            {
                throw new NoSuchPostException();
            }

            return _postToPostDtoMapper.Map(post);
        }
        public PostDTO CreatePost(BlogContext context, string sessionToken, string postText)
        {
            var user = _authenticationService.GetUserBySessionToken(context, sessionToken);
            var post = new Post
                {
                    User = user,
                    Text = postText,
                    CreatedAt = DateTime.UtcNow,
                    ModifiedAt = null,
                    Comments = new List<Comment>()
                };

            post = context.Posts.Add(post);
            context.SaveChanges();

            return _postToPostDtoMapper.Map(post);
        }
        public Page<BriefPostDTO> GetPosts(BlogContext context, string sessionToken, int itemsPerPage, int page)
        {
            _authenticationService.MakeSureSessionTokenIsOk(context, sessionToken);

            var postCount = context.Posts.Count();
            var posts = context.Posts
                .Include("User")
                .Include("Comments")
                .OrderBy(post => post.PostId)
                .Skip(page * itemsPerPage)
                .Take(itemsPerPage);

            return new Page<BriefPostDTO>
                {
                    TotalItemCount = postCount,
                    Items = _postToBriefPostDtoMapper.Map(posts)
                };
        }
        public void DeleteComment(BlogContext context, string sessionToken, int commentId)
        {
            var user = _authenticationService.GetUserBySessionToken(context, sessionToken);

            var comment = context.Comments.SingleOrDefault(c => c.CommentId == commentId);
            if (comment == null)
            {
                throw new NoSuchCommentException();
            }

            if (comment.UserId != user.UserId)
            {
                throw new NoPermissionsException();
            }

            context.Comments.Remove(comment);
            context.SaveChanges();
        }
        public UserDTO CreateUser(BlogContext context, string userName, string password)
        {
            var existingUser = context.Users.SingleOrDefault(u => u.UserName == userName);
            if (existingUser != null)
            {
                throw new UserNameAlreadyRegisteredException();
            }

            var user = new User
                {
                    UserName = userName,
                    Password = password,
                    CreatedAt = DateTime.UtcNow,
                    ModifiedAt = null
                };
            user = context.Users.Add(user);
            context.SaveChanges();

            return _userToUserDtoMapper.Map(user);
        }
        public UserDetailsDTO GetUserDetails(
            BlogContext context,
            string sessionToken,
            int userId,
            int maxNumberOfRecentPosts,
            int maxNumberOfRecentComments)
        {
            _authenticationService.MakeSureSessionTokenIsOk(context, sessionToken);

            var user = context.Users.SingleOrDefault(u => u.UserId == userId);
            if (user == null)
            {
                throw new NoSuchUserException();
            }

            var numberOfPosts = context.Posts.Count(post => post.UserId == userId);
            var recentPosts = context.Posts
                .Include("Comments")
                .Where(post => post.UserId == userId)
                .OrderByDescending(post => post.PostId)
                .Take(maxNumberOfRecentPosts)
                .ToList();

            var numberOfComments = context.Comments.Count(comment => comment.UserId == userId);
            var recentComments = context.Comments
                .Where(comment => comment.UserId == userId)
                .OrderByDescending(comment => comment.CommentId)
                .Take(maxNumberOfRecentComments)
                .ToList();

            return new UserDetailsDTO
                {
                    UserId = user.UserId,
                    UserName = user.UserName,
                    RegisteredAt = user.CreatedAt,
                    NumberOfPosts = numberOfPosts,
                    RecentPosts = _postToBriefPostDtoMapper.Map(recentPosts),
                    NumberOfComments = numberOfComments,
                    RecentComments = _commentToCommentDtoMapper.Map(recentComments)
                };
        }
        public CommentDTO UpdateComment(BlogContext context, string sessionToken, int commentId, string commentText)
        {
            var user = _authenticationService.GetUserBySessionToken(context, sessionToken);

            var comment = context.Comments.SingleOrDefault(c => c.CommentId == commentId);
            if (comment == null)
            {
                throw new NoSuchCommentException();
            }

            if (comment.UserId != user.UserId)
            {
                throw new NoPermissionsException();
            }

            comment.Text = commentText;
            comment.ModifiedAt = DateTime.UtcNow;

            context.SaveChanges();

            return _commentToCommentDtoMapper.Map(comment);
        }
        public IList<ActiveUserDTO> GetMostActiveUsers(BlogContext context, string sessionToken, int maxNumberOfMostActiveUsers)
        {
            _authenticationService.MakeSureSessionTokenIsOk(context, sessionToken);

            var activeUsers =
                (from post in context.Posts
                 group post by new
                     {
                         post.UserId,
                         post.User.UserName
                     }
                 into g
                 let postCount = g.Count()
                 orderby postCount descending
                 select new ActiveUserDTO
                     {
                         UserId = g.Key.UserId,
                         UserName = g.Key.UserName,
                         NumberOfPosts = postCount
                     }).Take(maxNumberOfMostActiveUsers).ToList();

            return activeUsers;
        }
        public PostDTO UpdatePost(BlogContext context, string sessionToken, int postId, string postText)
        {
            var user = _authenticationService.GetUserBySessionToken(context, sessionToken);
            var post = context.Posts
                .Include("Comments")
                .SingleOrDefault(p => p.PostId == postId);
            if (post == null)
            {
                throw new NoSuchPostException();
            }

            if (post.UserId != user.UserId)
            {
                throw new NoPermissionsException();
            }

            post.Text = postText;
            post.ModifiedAt = DateTime.UtcNow;

            context.SaveChanges();

            return _postToPostDtoMapper.Map(post);
        }
        public SessionDTO Authenticate(BlogContext context, string userName, string password)
        {
            var user = context.Users.SingleOrDefault(u => u.UserName == userName);
            if (user == null)
            {
                throw new NoSuchUserException();
            }

            if (user.Password != password)
            {
                throw new InvalidPasswordException();
            }

            var session = new Session
                {
                    SessionToken = Guid.NewGuid().ToString(),
                    User = user
                };

            session = context.Sessions.Add(session);
            context.SaveChanges();

            return _sessionToSessionDtoMapper.Map(session);
        }
        public CommentDTO CreateComment(BlogContext context, string sessionToken, int postId, string commentText)
        {
            var user = _authenticationService.GetUserBySessionToken(context, sessionToken);

            var post = context.Posts.SingleOrDefault(p => p.PostId == postId);
            if (post == null)
            {
                throw new NoSuchPostException();
            }

            var comment = new Comment
                {
                    Text = commentText,
                    CreatedAt = DateTime.UtcNow,
                    ModifiedAt = null,
                    Post = post,
                    User = user
                };

            context.Comments.Add(comment);
            context.SaveChanges();

            return _commentToCommentDtoMapper.Map(comment);
        }
 public void MakeSureSessionTokenIsOk(BlogContext context, string sessionToken)
 {
     GetUserBySessionToken(context, sessionToken);
 }