public HttpResponseMessage GetPostsPaging(
           [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey, int count, int page)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BlogDb();
                    using (context)
                    {
                        UserPersister.ValidateSessionKey(sessionKey);

                        var user = context.Users.FirstOrDefault(
                            usr => usr.SessionKey == sessionKey);

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

                        var posts = GetAll(sessionKey).Skip(page*count).Take(count).ToList();


                        var response =
                             this.Request.CreateResponse(HttpStatusCode.OK, posts);
                        return response;
                    }
                   
                });
            return responseMsg;
        }
        public HttpResponseMessage PostRegisterUser(UserModel model)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BlogDb();
                    using (context)
                    {
                        UserPersister.ValidateUsername(model.Username);
                        UserPersister.ValidateNickname(model.DisplayName);
                        UserPersister.ValidateAuthCode(model.AuthCode);
                        
                        var usernameToLower = model.Username.ToLower();
                        var nicknameToLower = model.DisplayName.ToLower();
                        
                        var user = context.Users.FirstOrDefault(
                            usr => usr.Username == usernameToLower ||
                                   usr.DisplayName.ToLower() == nicknameToLower);
                        
                        if (user != null)
                        {
                            throw new InvalidOperationException("User exists");
                        }
                        
                        user = new User()
                        {
                            Username = usernameToLower,
                            DisplayName = model.DisplayName,
                            AuthCode = model.AuthCode
                        };
                        
                        context.Users.Add(user);
                        context.SaveChanges();

                        user.SessionKey = UserPersister.GenerateSessionKey(user.UserId);
                        context.SaveChanges();
                        
                        var loggedModel = new UserLoggedModel()
                        {
                            DisplayName = user.DisplayName,
                            SessionKey = user.SessionKey
                        };
                        
                        var response =
                            this.Request.CreateResponse(HttpStatusCode.Created,
                                loggedModel);
                        return response;
                    }
                });
            
            return responseMsg;
        }
        public IQueryable<PostModel> GetAll(
           [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BlogDb();
                    using (context)
                    {
                        UserPersister.ValidateSessionKey(sessionKey);

                        var user = context.Users.FirstOrDefault(
                            usr => usr.SessionKey == sessionKey);

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

                      
                        var posts = context.Posts.Select(post => new PostModel
                        {
                            Id = post.PostId,
                            Title = post.Title,
                            DateOfCreation = post.DateCreated,
                            PostedBy = post.UserOfPost.DisplayName,
                            Content = post.Text,
                            Comments = post.Comments.Select(comment => new FullCommentInfoModel { 
                                 Content = comment.Content,
                                 DateOfCreating=comment.DateCreated,
                                 UserOfComment=comment.UserOfComment.DisplayName
                            }),
                            Tags = post.Tags.Select(tag => tag.TagName)
                        }).OrderBy(x=>x.DateOfCreation).ToList();
                            
                        
                         return posts.AsQueryable();
                          
                    }
                });
                       return responseMsg;
    
        }
        public HttpResponseMessage CreateComment([ValueProvider(typeof(HeaderValueProviderFactory<string>))]string sessionKey,
            int postId, [FromBody]CreateCommentModel comment)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BlogDb();
                    using (context)
                    {

                        UserPersister.ValidateSessionKey(sessionKey);

                        var user = context.Users.FirstOrDefault(
                            usr => usr.SessionKey == sessionKey);

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

                        var post = context.Posts.FirstOrDefault(p => p.PostId == postId);
                        if (post == null)
                        {
                             throw new ArgumentNullException("Invalid post id");
                        }

                        Comment commToAdd = new Comment()  
                        { 
                             Content= comment.Text,
                             UserOfComment = user,
                             DateCreated = DateTime.Now
                        };

                        post.Comments.Add(commToAdd);
                        context.SaveChanges();

                        var response =
                           this.Request.CreateResponse(HttpStatusCode.OK);
                        return response;
                    }
                });
            return responseMsg;
        }
        public HttpResponseMessage GetTagsById([ValueProvider(typeof(HeaderValueProviderFactory<string>))]string sessionKey, int tagId)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BlogDb();
                    using (context)
                    {

                        UserPersister.ValidateSessionKey(sessionKey);

                        var user = context.Users.FirstOrDefault(
                            usr => usr.SessionKey == sessionKey);

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

                       
                        var tag = context.Tags.FirstOrDefault(x=>x.TagId == tagId);

                        PostsController controler = new PostsController();


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

                        var posts = controler.GetAll(sessionKey).Where(x => x.Tags.Contains(tag.TagName)).ToList();
                        

                       

                        var response =
                            this.Request.CreateResponse(HttpStatusCode.OK,
                                posts);
                        return response;
                    }
                });
            return responseMsg;
        }
        public HttpResponseMessage GetAll([ValueProvider(typeof(HeaderValueProviderFactory<string>))]string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BlogDb();
                    using (context)
                    {

                        UserPersister.ValidateSessionKey(sessionKey);

                        var user = context.Users.FirstOrDefault(
                            usr => usr.SessionKey == sessionKey);

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

                        var tags = new List<TagsModel>();

                        var tagsFromDB = context.Tags.Include("Posts").ToList();

                        for (int i = 0; i < tagsFromDB.Count(); i++)
                        {
                            tags.Add(new TagsModel()
                            {
                                Id = tagsFromDB[i].TagId,
                                Name = tagsFromDB[i].TagName,
                                Posts = tagsFromDB[i].Posts.Count
                            });
                        }

                        tags.OrderBy(x => x.Id);

                        var response =
                            this.Request.CreateResponse(HttpStatusCode.OK,
                                tags);
                        return response;
                    }
                });
            return responseMsg;
        }
        public HttpResponseMessage PutLogoutUser([ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BlogDb();
                    using (context)
                    {
                        UserPersister.ValidateSessionKey(sessionKey);

                        var user = context.Users.FirstOrDefault(usr => usr.SessionKey == sessionKey);
                        if (user == null)
                        {
                            throw new InvalidOperationException("Invalid session key.");
                        }
                        else
                        {
                            user.SessionKey = null;
                            context.SaveChanges();
                        }
                    }
                    
                    var response =
                        this.Request.CreateResponse(HttpStatusCode.OK);
                    
                    return response;
                });
            
            return responseMsg;
        }
        public HttpResponseMessage PostCreatePost(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey ,
            [FromBody]CreatePostModel postToAdd)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BlogDb();
                    using (context)
                    {
                        UserPersister.ValidateSessionKey(sessionKey);

                        var user = context.Users.FirstOrDefault(
                            usr => usr.SessionKey == sessionKey);

                        if (user == null)
                        {
                            throw new InvalidOperationException("Invalid username or password");
                        }
                        List<Tag> tags = new List<Tag>();
                       
                        var wordsFromTitle = postToAdd.Title.Split(new char[] { ' ', ',' },
                            StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < wordsFromTitle.Length; i++)
                        {
                            tags.Add(new Tag() { TagName = wordsFromTitle[i].ToLower() });
                        }
                      
                        for (int i = 0; i < postToAdd.Tags.Length; i++)
                        {
                            tags.Add(new Tag() { TagName = postToAdd.Tags[i].ToLower() });
                        }

                        var post = new Post()
                        {
                            Title = postToAdd.Title,
                            DateCreated = DateTime.Now,
                            UserOfPost = user,
                            Text = postToAdd.Text,
                            Tags = tags
                        };
                       
                        context.Posts.Add(post);
                        context.SaveChanges();

                        CreatedPostModel postModel = new CreatedPostModel() { Id = post.PostId, Title = post.Title };
                      

                        var response =
                            this.Request.CreateResponse(HttpStatusCode.Created,
                                postModel);
                        return response;
                    }
                });

            return responseMsg;
        }
        public HttpResponseMessage GetPostsByTags(
           [ValueProvider(typeof(HeaderValueProviderFactory<string>))] string sessionKey, string tags)
        {
            var responseMsg = this.PerformOperationAndHandleExceptions(
                () =>
                {
                    var context = new BlogDb();
                    using (context)
                    {
                        UserPersister.ValidateSessionKey(sessionKey);

                        var user = context.Users.FirstOrDefault(
                            usr => usr.SessionKey == sessionKey);

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

                       
                        //f**k can't do it the easy way :( ...

                        var tagsSplited = tags.Split(',');


                        var postsResult = GetAll(sessionKey);
                      
                       
                        
                        var response =
                             this.Request.CreateResponse(HttpStatusCode.OK, postsResult);
                        return response;
                    }

                });
            return responseMsg;
        }