public HttpResponseMessage EditRecipe([FromUri]int id, RecipeModel model,
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))]
            string accessToken)
        {
            return this.ExecuteOperationAndHandleExceptions(() =>
            {
                var context = new RecipeContext();

                var user = this.GetUserByAccessToken(accessToken, context);

                this.ValidateRecipe(model);

                var recipeEntity = this.GetRecipeById(id, context);

                recipeEntity.Name = model.Name;
                recipeEntity.Products = model.Products;
                recipeEntity.CookingSteps = model.CookingSteps;
                recipeEntity.ImagePath = model.ImagePath;

                context.SaveChanges();

                var responseModel = new RecipeCreatedModel()
                {
                    Id = recipeEntity.RecepieId
                };

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

                return response;
            });
        }
        public HttpResponseMessage CreateComment(CommentModel model, 
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))]
            string accessToken)
        {
            return this.ExecuteOperationAndHandleExceptions(() =>
            {
                var context = new RecipeContext();
                var meUser = this.GetUserByAccessToken(accessToken, context);
                var recipe = this.GetRecipeById(model.RecepieId,context);

                this.ValidateComment(model);

                var commentEntity = new Comment
                {
                    Text = model.Text,
                    Recepy = recipe,
                    User = meUser
                };
                context.Comments.Add(commentEntity);
                context.SaveChanges();

                var responseModel = new CreatedComment()
                {
                    Id = commentEntity.CommentId,
                    OwnerId = commentEntity.UserId
                };
                var response = this.Request.CreateResponse(HttpStatusCode.Created, responseModel);
                return response;
            });
        }
        public HttpResponseMessage LogoutUser(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))]
            string accessToken)
        {
            return this.ExecuteOperationAndHandleExceptions(() =>
            {
                var context = new RecipeContext();
                var user = this.GetUserByAccessToken(accessToken, context);
                user.AccessToken = null;
                context.SaveChanges();

                var response = this.Request.CreateResponse(HttpStatusCode.NoContent);
                return response;
            });
        }
        public IQueryable<CommentModel> GetAll(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))]
            string accessToken)
        {
            return this.ExecuteOperationAndHandleExceptions(() =>
            {
                var context = new RecipeContext();
                var user = this.GetUserByAccessToken(accessToken, context);

                var commentsList = context.Comments.AsQueryable().OrderBy(cm => cm.Text).Select(cm => new CommentModel()
                {
                    Id = cm.CommentId,
                    Text = cm.Text,
                    RecepieId = cm.RecepieId
                });
                return commentsList;
            });
        }
        public HttpResponseMessage LoginUser(UserModel model)
        {
            return this.ExecuteOperationAndHandleExceptions(() =>
            {
                //this.ValidateUser(model);
                if (model == null)
                {
                    throw new FormatException("invalid username and/or password");
                }
                this.ValidateAuthCode(model.AuthCode);
                this.ValidateUsername(model.Username);

                var context = new RecipeContext();
                var username = (model.Username).ToLower();
                var user = context.Users.FirstOrDefault(u => u.UserName == username);
                if (user == null)
                {
                    throw new InvalidOperationException("Invalid username");
                }
                if (user.AuthenticationCode != model.AuthCode)
                {
                    throw new InvalidOperationException("Invalid password");
                }
                if (user.AccessToken == null)
                {
                    user.AccessToken = this.GenerateAccessToken(user.UserId);
                    context.SaveChanges();
                }
                var responseModel = new LoginResponseModel()
                {
                    Id = user.UserId,
                    Username = user.UserName,
                    AccessToken = user.AccessToken
                };
                var response = this.Request.CreateResponse(HttpStatusCode.OK, responseModel);
                return response;
            });
        }
        public HttpResponseMessage RegisterUser(UserModel model)
        {
            return this.ExecuteOperationAndHandleExceptions(() =>
            {
                this.ValidateUser(model);

                var context = new RecipeContext();
                var dbUser = GetUserByUsername(model, context);
                if (dbUser != null)
                {
                    throw new InvalidOperationException("This user already exists in the database");
                }
                dbUser = new User()
                {
                    UserName = model.Username,
                    AuthenticationCode = model.AuthCode
                };
                context.Users.Add(dbUser);

                context.SaveChanges();

                var responseModel = new RegisterUserResponseModel()
                {
                    Id = dbUser.UserId,
                    Username = dbUser.UserName,
                };

                var response = this.Request.CreateResponse(HttpStatusCode.Created, responseModel);
                return response;
            });
        }
 private User GetUserByUsername(UserModel model, RecipeContext context)
 {
     var usernameToLower = model.Username.ToLower();
     var dbUser = context.Users.FirstOrDefault(u => u.UserName == usernameToLower);
     return dbUser;
 }
        public RecipeModel Get([FromUri]int id)
        {
            return this.ExecuteOperationAndHandleExceptions(() =>
            {
                var context = new RecipeContext();

                var recipe = this.GetRecipeById(id, context);

                var recipeModel = new RecipeModel() {
                    Id = recipe.RecepieId,
                    Name = recipe.Name,
                    CookingSteps = recipe.CookingSteps,
                    Products = recipe.Products,
                    ImagePath = recipe.ImagePath
                };
                return recipeModel;
            });
        }
        public IQueryable<RecipeModel> GetAll()
        {
            return this.ExecuteOperationAndHandleExceptions(() =>
            {
                var context = new RecipeContext();

                var recipeModels = context.Recepies
                    .AsQueryable()
                    .OrderByDescending(rec => rec.Name)
                    .Select(rec => new RecipeModel()
                    {
                        Id = rec.RecepieId,
                        Name = rec.Name,
                        CookingSteps = rec.CookingSteps,
                        Products = rec.Products,
                        ImagePath = rec.ImagePath
                    });

                return recipeModels;
            });
        }
        public IQueryable<RecipeModel> GetAll(
            [ValueProvider(typeof(HeaderValueProviderFactory<string>))]
            string accessToken)
        {
            return this.ExecuteOperationAndHandleExceptions(() =>
            {
                var context = new RecipeContext();
                var user = this.GetUserByAccessToken(accessToken, context);

                var recipeModels = user.Recepies
                    .AsQueryable()
                    .OrderByDescending(rec => rec.Name)
                    .Select(rec => new RecipeModel() {
                        Id = rec.RecepieId,
                        Name = rec.Name,
                        CookingSteps = rec.CookingSteps,
                        Products = rec.Products,
                        ImagePath = rec.ImagePath
                    });

                return recipeModels;
            });
        }