// Path: sample-app/src/main/java/virtua/training/polymer/mvc/todo/model/User.java
// public class User implements Serializable {
// 
//     private String userId;
// 
//     private String password;
// 
//     public User() {
//     }
// 
//     public User(String userId, String password) {
//         this.userId = userId;
//         this.password = password;
//     }
// 
//     public String getUserId() {
//         return userId;
//     }
// 
//     public void setUserId(String userId) {
//         this.userId = userId;
//     }
// 
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// }
// 
// Path: sample-app/src/main/java/virtua/training/polymer/mvc/todo/service/UserService.java
// @ApplicationScoped
// public class UserService {
// 
//     private List<User> activeUsers;
//     private Map<String, User> users;
//     private User systemUser;
// 
//     public UserService() {
//         activeUsers = new ArrayList<>();
//         users = new ConcurrentHashMap<>();
//         systemUser = add("System", "password1");
//     }
// 
//     /**
//      * Logs a user in and adds them to the active user list. If the user doesn't exist, creates the user.
//      */
//     public Optional<User> login(String userId, String password) {
//         User user = getUsers().get(userId);
//         if (user == null) {
//             user = add(userId, password);
//         } else if (user.getPassword().equals(password)) {
//             getActiveUsers().add(user);
//             getUsers().put(userId, user);
//         } else {
//             user = null;
//         }
//         return Optional.ofNullable(user);
//     }
// 
//     public User add(String userId, String password) {
//         User user = new User(userId, password);
//         getUsers().put(userId, user);
//         return user;
//     }
// 
//     public List<User> getActiveUsers() {
//         return activeUsers;
// 
//     }
// 
//     public boolean userExists(String userId) {
//         return getUsers().containsKey(userId);
//     }
// 
//     public Map<String, User> getUsers() {
//         return users;
//     }
// 
//     public void logout(User user) {
//         getActiveUsers().remove(user);
//     }
// 
//     public User getSystemUser() {
//         return systemUser;
//     }
// }
// 
// Path: sample-app/src/main/java/virtua/training/polymer/mvc/todo/util/Messages.java
// @Named
// @RedirectScoped
// public class Messages implements Serializable {
// 
//     private static final long serialVersionUID = 6012270416224546642L;
// 
//     private String info;
// 
//     private final List<String> errors = new ArrayList<>();
// 
//     public Messages addError(String error) {
//         errors.add(error);
//         return this;
//     }
// 
//     public List<String> getErrors() {
//         return Collections.unmodifiableList(errors);
//     }
// 
//     public String getInfo() {
//         return info;
//     }
// 
//     public void setInfo(String info) {
//         this.info = info;
//     }
// 
// }


import virtua.training.polymer.mvc.todo.model.User;
import virtua.training.polymer.mvc.todo.service.UserService;
import virtua.training.polymer.mvc.todo.util.Messages;
import javax.inject.Inject;
import javax.mvc.Models;
import javax.mvc.Viewable;
import javax.mvc.annotation.Controller;
import javax.mvc.annotation.CsrfValid;
import javax.mvc.annotation.RedirectScoped;
import javax.mvc.binding.BindingResult;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import javax.validation.executable.ExecutableType;
import javax.validation.executable.ValidateOnExecution;
import javax.ws.rs.BeanParam;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.io.Serializable;
import java.util.Optional;
import java.util.logging.Logger;
     * Performs a login using form parameters and adds the user to the session. Performs no validation.
     */
    @Path("login-no-validation")
    @POST
    @CsrfValid
    public String login(@FormParam("userId") String userId, @FormParam("password") String password) {
        Optional<User> loginResult = userService.login(userId, password);
        if (loginResult.isPresent()) {
            session.setAttribute("user", loginResult.get());
            return "redirect:../facelets/todo.html";
            // Equivalent to:
            // Response.temporaryRedirect(URI.create("../todo.html")).build();
        }
        models.put("userId", userId);
        models.put("loginError", true);
        return "/login.jsp";
        // Equivalent to:
        // Viewable view = new Viewable("../login.jsp");
    }

    /**
     * Performs a login using form parameters and adds the user to the session.
     * Uses BindingResults and bean validation.
     */
    @Path("login-validation")
    @POST
    @CsrfValid
    @ValidateOnExecution(type = ExecutableType.NONE)
    public String login(@BeanParam @Valid LoginForm loginForm) {

// Path: sample-app/src/main/java/virtua/training/polymer/mvc/todo/model/User.java
// public class User implements Serializable {
// 
//     private String userId;
// 
//     private String password;
// 
//     public User() {
//     }
// 
//     public User(String userId, String password) {
//         this.userId = userId;
//         this.password = password;
//     }
// 
//     public String getUserId() {
//         return userId;
//     }
// 
//     public void setUserId(String userId) {
//         this.userId = userId;
//     }
// 
//     public String getPassword() {
//         return password;
//     }
// 
//     public void setPassword(String password) {
//         this.password = password;
//     }
// }
// 
// Path: sample-app/src/main/java/virtua/training/polymer/mvc/todo/service/UserService.java
// @ApplicationScoped
// public class UserService {
// 
//     private List<User> activeUsers;
//     private Map<String, User> users;
//     private User systemUser;
// 
//     public UserService() {
//         activeUsers = new ArrayList<>();
//         users = new ConcurrentHashMap<>();
//         systemUser = add("System", "password1");
//     }
// 
//     /**
//      * Logs a user in and adds them to the active user list. If the user doesn't exist, creates the user.
//      */
//     public Optional<User> login(String userId, String password) {
//         User user = getUsers().get(userId);
//         if (user == null) {
//             user = add(userId, password);
//         } else if (user.getPassword().equals(password)) {
//             getActiveUsers().add(user);
//             getUsers().put(userId, user);
//         } else {
//             user = null;
//         }
//         return Optional.ofNullable(user);
//     }
// 
//     public User add(String userId, String password) {
//         User user = new User(userId, password);
//         getUsers().put(userId, user);
//         return user;
//     }
// 
//     public List<User> getActiveUsers() {
//         return activeUsers;
// 
//     }
// 
//     public boolean userExists(String userId) {
//         return getUsers().containsKey(userId);
//     }
// 
//     public Map<String, User> getUsers() {
//         return users;
//     }
// 
//     public void logout(User user) {
//         getActiveUsers().remove(user);
//     }
// 
//     public User getSystemUser() {
//         return systemUser;
//     }
// }
// 
// Path: sample-app/src/main/java/virtua/training/polymer/mvc/todo/util/Messages.java
// @Named
// @RedirectScoped
// public class Messages implements Serializable {
// 
//     private static final long serialVersionUID = 6012270416224546642L;
// 
//     private String info;
// 
//     private final List<String> errors = new ArrayList<>();
// 
//     public Messages addError(String error) {
//         errors.add(error);
//         return this;
//     }
// 
//     public List<String> getErrors() {
//         return Collections.unmodifiableList(errors);
//     }
// 
//     public String getInfo() {
//         return info;
//     }
// 
//     public void setInfo(String info) {
//         this.info = info;
//     }
// 
// }


// Path: sample-app/src/main/java/virtua/training/polymer/mvc/todo/controller/AuthenticationController.java
import virtua.training.polymer.mvc.todo.model.User;
import virtua.training.polymer.mvc.todo.service.UserService;
import virtua.training.polymer.mvc.todo.util.Messages;
import javax.inject.Inject;
import javax.mvc.Models;
import javax.mvc.Viewable;
import javax.mvc.annotation.Controller;
import javax.mvc.annotation.CsrfValid;
import javax.mvc.annotation.RedirectScoped;
import javax.mvc.binding.BindingResult;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import javax.validation.executable.ExecutableType;
import javax.validation.executable.ValidateOnExecution;
import javax.ws.rs.BeanParam;
import javax.ws.rs.FormParam;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import java.io.Serializable;
import java.util.Optional;
import java.util.logging.Logger;

     * Performs a login using form parameters and adds the user to the session. Performs no validation.
     */
    @Path("login-no-validation")
    @POST
    @CsrfValid
    public String login(@FormParam("userId") String userId, @FormParam("password") String password) {
        Optional<User> loginResult = userService.login(userId, password);
        if (loginResult.isPresent()) {
            session.setAttribute("user", loginResult.get());
            return "redirect:../facelets/todo.html";
            // Equivalent to:
            // Response.temporaryRedirect(URI.create("../todo.html")).build();
        }
        models.put("userId", userId);
        models.put("loginError", true);
        return "/login.jsp";
        // Equivalent to:
        // Viewable view = new Viewable("../login.jsp");
    }

    /**
     * Performs a login using form parameters and adds the user to the session.
     * Uses BindingResults and bean validation.
     */
    @Path("login-validation")
    @POST
    @CsrfValid
    @ValidateOnExecution(type = ExecutableType.NONE)
    public String login(@BeanParam @Valid LoginForm loginForm) {

        if (bindingResult.isFailed()) {