// Path: app/edu/indiana/d2i/htrc/portal/exception/ChangePasswordUserAdminExceptionException.java
// public class ChangePasswordUserAdminExceptionException extends Exception {
//     public ChangePasswordUserAdminExceptionException() {
//         super();
//     }
// 
//     public ChangePasswordUserAdminExceptionException(String message) {
//         super(message);
//     }
// 
//     public ChangePasswordUserAdminExceptionException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public ChangePasswordUserAdminExceptionException(Throwable cause) {
//         super(cause);
//     }
// 
//     protected ChangePasswordUserAdminExceptionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// }
// 
// Path: app/edu/indiana/d2i/htrc/portal/exception/UserAlreadyExistsException.java
// public class UserAlreadyExistsException extends Exception {
//     public UserAlreadyExistsException(String message) {
//         super(message);
//     }
// 
//     public UserAlreadyExistsException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public UserAlreadyExistsException(Throwable cause) {
//         super(cause);
//     }
// }
// 
// Path: app/models/Token.java
// @Entity
// public class Token extends Model {
//     @Id
//     @GeneratedValue(strategy = GenerationType.IDENTITY)
//     public Long id;
//     public String userId;
//     public String token;
//     public Long createdTime;
//     public String isTokenUsed = "NO";
// 
//     private static Logger.ALogger log = play.Logger.of("application");
//     private static long validityPeriod = 3600; // in seconds
// 
//     public Token(String userId, String token, Long createdTime) {
//         this.userId = userId;
//         this.token = token;
//         this.createdTime = createdTime;
//     }
// 
//     public static Finder<Long, Token> find = new Finder<Long, Token>(Long.class, Token.class);
// 
//     public static Token findByToken(String token){
//         log.info("Looking for token: "+ token);
//         return find.where().eq("token", token).findUnique();
//     }
// 
//     public static String generateToken(String userId, String userEmail) throws NoSuchAlgorithmException, UnsupportedEncodingException {
//         char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
// 
//         MessageDigest messageDigestInstance = MessageDigest.getInstance("SHA-256");
// 
//         byte[] hash = messageDigestInstance.digest((new Date().toString() + userId + userEmail).getBytes("UTF-8"));
//         StringBuilder sb = new StringBuilder(hash.length * 2);
//         for (byte b : hash) {
//             sb.append(HEX_CHARS[(b & 0xF0) >> 4]);
//             sb.append(HEX_CHARS[b & 0x0F]);
//         }
// 
//         String newToken = sb.toString();
//         if(Token.findByToken(newToken) != null){
//             Token alreadyExistToken = Token.findByToken(newToken);
//             log.info("Token: "+newToken+" is already exist.");
//             if(alreadyExistToken.userId.equals(userId)){
//                 alreadyExistToken.createdTime = new Date().getTime();
//                 alreadyExistToken.update();
//             }else{
//                 log.error("Error in saving tokens.");
//             }
// 
//         }else {
//             Token token = new Token(userId,newToken,new Date().getTime());
//             token.save();
//             log.info("Token :"+ Token.findByToken(newToken).token + " is saved successfully.");
//         }
//         return newToken;
//     }
// 
//     public static void deleteToken(String token){
//        Token token1 = Token.findByToken(token);
//         if(token1 != null){
//             token1.delete();
//         }
//     }
// 
//     public static void replaceToken(Token token1){
//         token1.update();
//     }
// 
//     public static void deleteAllTokens(){
//         List<Token> tokenList = find.all();
//         for(Token token1 : tokenList){
//              token1.delete();
//         }
// 
//     }
// 
//     public static boolean isTokenExpired(Token token){
//         log.info("Validity period = " + validityPeriod + " Current time = " + new Date().getTime());
// 
//         return validityPeriod < (new Date().getTime() - token.createdTime)/1000;
//     }
// 
// 
// 
// }


import com.fasterxml.jackson.databind.node.ObjectNode;
import edu.indiana.d2i.htrc.portal.*;
import edu.indiana.d2i.htrc.portal.exception.ChangePasswordUserAdminExceptionException;
import edu.indiana.d2i.htrc.portal.exception.UserAlreadyExistsException;
import models.Token;
import org.pac4j.play.java.JavaController;
import play.Logger;
import play.data.Form;
import play.libs.Json;
import play.mvc.Result;
import views.html.*;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.rmi.RemoteException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import static play.data.Form.form;
        HTRCUserManagerUtility userManager = HTRCUserManagerUtility.getInstanceWithDefaultProperties();
        PasswordChecker passwordChecker = new PasswordChecker();

        public String validate() {
            if (userId.isEmpty() || password.isEmpty()
                    || confirmPassword.isEmpty() || firstName.isEmpty()
                    || lastName.isEmpty() || email.isEmpty() || confirmEmail.isEmpty()) {

                return "Please fill all the fields.";
            }
            log.info("User ID: " + userId);
            if (userId.contains("@")) {
                return "User ID must not contain '@' sign. ";
            }
            if (userManager.isUserExists(userId)) {
                return "Username already exists.";
            }

            if (userManager.roleNameExists(userId)) {
                return "There's a role name already exists with this name. Please use another username.";
            }
            try {
                usersWithEmail = userManager.getUserIdsFromEmail(email);
                if (usersWithEmail != null && usersWithEmail.size() > 0){
                    return email + " is already used for user accounts: " + usersWithEmail;
                }
            } catch (RemoteException e) {
                log.error("Error when checking email availability.");
            }

// Path: app/edu/indiana/d2i/htrc/portal/exception/ChangePasswordUserAdminExceptionException.java
// public class ChangePasswordUserAdminExceptionException extends Exception {
//     public ChangePasswordUserAdminExceptionException() {
//         super();
//     }
// 
//     public ChangePasswordUserAdminExceptionException(String message) {
//         super(message);
//     }
// 
//     public ChangePasswordUserAdminExceptionException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public ChangePasswordUserAdminExceptionException(Throwable cause) {
//         super(cause);
//     }
// 
//     protected ChangePasswordUserAdminExceptionException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
//         super(message, cause, enableSuppression, writableStackTrace);
//     }
// }
// 
// Path: app/edu/indiana/d2i/htrc/portal/exception/UserAlreadyExistsException.java
// public class UserAlreadyExistsException extends Exception {
//     public UserAlreadyExistsException(String message) {
//         super(message);
//     }
// 
//     public UserAlreadyExistsException(String message, Throwable cause) {
//         super(message, cause);
//     }
// 
//     public UserAlreadyExistsException(Throwable cause) {
//         super(cause);
//     }
// }
// 
// Path: app/models/Token.java
// @Entity
// public class Token extends Model {
//     @Id
//     @GeneratedValue(strategy = GenerationType.IDENTITY)
//     public Long id;
//     public String userId;
//     public String token;
//     public Long createdTime;
//     public String isTokenUsed = "NO";
// 
//     private static Logger.ALogger log = play.Logger.of("application");
//     private static long validityPeriod = 3600; // in seconds
// 
//     public Token(String userId, String token, Long createdTime) {
//         this.userId = userId;
//         this.token = token;
//         this.createdTime = createdTime;
//     }
// 
//     public static Finder<Long, Token> find = new Finder<Long, Token>(Long.class, Token.class);
// 
//     public static Token findByToken(String token){
//         log.info("Looking for token: "+ token);
//         return find.where().eq("token", token).findUnique();
//     }
// 
//     public static String generateToken(String userId, String userEmail) throws NoSuchAlgorithmException, UnsupportedEncodingException {
//         char[] HEX_CHARS = "0123456789ABCDEF".toCharArray();
// 
//         MessageDigest messageDigestInstance = MessageDigest.getInstance("SHA-256");
// 
//         byte[] hash = messageDigestInstance.digest((new Date().toString() + userId + userEmail).getBytes("UTF-8"));
//         StringBuilder sb = new StringBuilder(hash.length * 2);
//         for (byte b : hash) {
//             sb.append(HEX_CHARS[(b & 0xF0) >> 4]);
//             sb.append(HEX_CHARS[b & 0x0F]);
//         }
// 
//         String newToken = sb.toString();
//         if(Token.findByToken(newToken) != null){
//             Token alreadyExistToken = Token.findByToken(newToken);
//             log.info("Token: "+newToken+" is already exist.");
//             if(alreadyExistToken.userId.equals(userId)){
//                 alreadyExistToken.createdTime = new Date().getTime();
//                 alreadyExistToken.update();
//             }else{
//                 log.error("Error in saving tokens.");
//             }
// 
//         }else {
//             Token token = new Token(userId,newToken,new Date().getTime());
//             token.save();
//             log.info("Token :"+ Token.findByToken(newToken).token + " is saved successfully.");
//         }
//         return newToken;
//     }
// 
//     public static void deleteToken(String token){
//        Token token1 = Token.findByToken(token);
//         if(token1 != null){
//             token1.delete();
//         }
//     }
// 
//     public static void replaceToken(Token token1){
//         token1.update();
//     }
// 
//     public static void deleteAllTokens(){
//         List<Token> tokenList = find.all();
//         for(Token token1 : tokenList){
//              token1.delete();
//         }
// 
//     }
// 
//     public static boolean isTokenExpired(Token token){
//         log.info("Validity period = " + validityPeriod + " Current time = " + new Date().getTime());
// 
//         return validityPeriod < (new Date().getTime() - token.createdTime)/1000;
//     }
// 
// 
// 
// }


// Path: app/controllers/UserManagement.java
import com.fasterxml.jackson.databind.node.ObjectNode;
import edu.indiana.d2i.htrc.portal.*;
import edu.indiana.d2i.htrc.portal.exception.ChangePasswordUserAdminExceptionException;
import edu.indiana.d2i.htrc.portal.exception.UserAlreadyExistsException;
import models.Token;
import org.pac4j.play.java.JavaController;
import play.Logger;
import play.data.Form;
import play.libs.Json;
import play.mvc.Result;
import views.html.*;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import java.io.UnsupportedEncodingException;
import java.rmi.RemoteException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import static play.data.Form.form;

        HTRCUserManagerUtility userManager = HTRCUserManagerUtility.getInstanceWithDefaultProperties();
        PasswordChecker passwordChecker = new PasswordChecker();

        public String validate() {
            if (userId.isEmpty() || password.isEmpty()
                    || confirmPassword.isEmpty() || firstName.isEmpty()
                    || lastName.isEmpty() || email.isEmpty() || confirmEmail.isEmpty()) {

                return "Please fill all the fields.";
            }
            log.info("User ID: " + userId);
            if (userId.contains("@")) {
                return "User ID must not contain '@' sign. ";
            }
            if (userManager.isUserExists(userId)) {
                return "Username already exists.";
            }

            if (userManager.roleNameExists(userId)) {
                return "There's a role name already exists with this name. Please use another username.";
            }
            try {
                usersWithEmail = userManager.getUserIdsFromEmail(email);
                if (usersWithEmail != null && usersWithEmail.size() > 0){
                    return email + " is already used for user accounts: " + usersWithEmail;
                }
            } catch (RemoteException e) {
                log.error("Error when checking email availability.");
            }

            if (passwordValidate(password, confirmPassword,userId) != null) {