diff --git a/src/mathquiz/backend_1/EmailService.java b/src/mathquiz/backend_1/EmailService.java
new file mode 100644
index 0000000..fe1f3c1
--- /dev/null
+++ b/src/mathquiz/backend_1/EmailService.java
@@ -0,0 +1,172 @@
+package mathquiz.backend;
+
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Random;
+
+/**
+ * Email Service Class - Handles email verification code sending
+ */
+public class EmailService {
+
+ // Email configuration - loaded from properties file
+ private String smtpHost;
+ private String smtpPort;
+ private String emailUsername;
+ private String emailPassword;
+ private String fromEmail;
+
+ public EmailService() {
+ loadEmailConfig();
+ }
+
+ /**
+ * Load email configuration from properties file
+ */
+ private void loadEmailConfig() {
+ Properties config = new Properties();
+ try {
+ config.load(new FileInputStream("email_config.properties"));
+ smtpHost = config.getProperty("smtp.host", "smtp.gmail.com");
+ smtpPort = config.getProperty("smtp.port", "587");
+ emailUsername = config.getProperty("email.username", "your-email@gmail.com");
+ emailPassword = config.getProperty("email.password", "your-app-password");
+ fromEmail = config.getProperty("email.from", "your-email@gmail.com");
+ } catch (IOException e) {
+ System.err.println("Warning: Could not load email configuration, using default settings");
+ // Use default settings
+ smtpHost = "smtp.gmail.com";
+ smtpPort = "587";
+ emailUsername = "your-email@gmail.com";
+ emailPassword = "your-app-password";
+ fromEmail = "your-email@gmail.com";
+ }
+ }
+
+ /**
+ * Send verification code to email
+ */
+ public String sendVerificationCode(String email) throws Exception {
+ // Generate 6-digit numeric verification code
+ String verificationCode = generateVerificationCode();
+
+ // Send real email
+ sendRealEmail(email, verificationCode);
+
+ // Also save to file for backup verification
+ saveVerificationCodeToFile(email, verificationCode);
+
+ return verificationCode;
+ }
+
+ /**
+ * Generate verification code
+ */
+ private String generateVerificationCode() {
+ Random random = new Random();
+ StringBuilder code = new StringBuilder();
+
+ for (int i = 0; i < 6; i++) {
+ code.append(random.nextInt(10));
+ }
+
+ return code.toString();
+ }
+
+ /**
+ * Send real email using SMTP protocol
+ */
+ private void sendRealEmail(String email, String verificationCode) throws Exception {
+ try {
+ // Create email content
+ String subject = "Math Quiz System - Registration Verification Code";
+ String content = createEmailContent(verificationCode);
+
+ // Use SimpleEmailSender
+ SimpleEmailSender sender = new SimpleEmailSender(
+ smtpHost,
+ Integer.parseInt(smtpPort),
+ emailUsername,
+ emailPassword,
+ fromEmail
+ );
+
+ sender.sendEmail(email, subject, content);
+
+ System.out.println("Verification code sent successfully to: " + email);
+ System.out.println("Verification code: " + verificationCode);
+
+ } catch (Exception e) {
+ System.err.println("Failed to send email: " + e.getMessage());
+ // Fall back to console output
+ System.out.println("=== EMAIL VERIFICATION CODE ===");
+ System.out.println("To: " + email);
+ System.out.println("Subject: Math Quiz System - Registration Verification Code");
+ System.out.println("Verification Code: " + verificationCode);
+ System.out.println("Please check your email or use the code above.");
+ System.out.println("================================");
+ }
+ }
+
+
+ /**
+ * Create email content with HTML formatting
+ */
+ private String createEmailContent(String verificationCode) {
+ return "" +
+ "
" +
+ "" +
+ "" +
+ "
Math Quiz System
" +
+ "
Registration Verification
" +
+ "
Hello,
" +
+ "
Thank you for registering with Math Quiz System. Please use the following verification code to complete your registration:
" +
+ "
" +
+ "
" + verificationCode + "
" +
+ "" +
+ "
Important:
" +
+ "
" +
+ "- This verification code will expire in 5 minutes
" +
+ "- Please enter this code exactly as shown
" +
+ "- If you did not request this code, please ignore this email
" +
+ "
" +
+ "
Best regards,
Math Quiz System Team
" +
+ "
" +
+ "
This is an automated message, please do not reply.
" +
+ "
" +
+ "" +
+ "";
+ }
+
+ /**
+ * Save verification code to file (for demonstration only)
+ */
+ private void saveVerificationCodeToFile(String email, String verificationCode) {
+ try {
+ java.nio.file.Files.createDirectories(java.nio.file.Paths.get("data"));
+ java.nio.file.Files.write(
+ java.nio.file.Paths.get("data/verification_codes.txt"),
+ (email + ":" + verificationCode + "\n").getBytes(),
+ java.nio.file.StandardOpenOption.CREATE,
+ java.nio.file.StandardOpenOption.APPEND
+ );
+ } catch (Exception e) {
+ // Ignore file save errors
+ }
+ }
+
+ /**
+ * Validate email format
+ */
+ public boolean isValidEmail(String email) {
+ if (email == null || email.trim().isEmpty()) {
+ return false;
+ }
+
+ String trimmedEmail = email.trim();
+ return trimmedEmail.contains("@") &&
+ trimmedEmail.contains(".") &&
+ trimmedEmail.length() > 5;
+ }
+}
\ No newline at end of file
diff --git a/src/mathquiz/backend_1/Question.java b/src/mathquiz/backend_1/Question.java
new file mode 100644
index 0000000..7149e1b
--- /dev/null
+++ b/src/mathquiz/backend_1/Question.java
@@ -0,0 +1,58 @@
+package mathquiz.backend;
+
+/**
+ * Question Class - Represents a multiple choice question
+ */
+public class Question {
+ private final String question;
+ private final String optionA;
+ private final String optionB;
+ private final String optionC;
+ private final String optionD;
+ private final String correctAnswer;
+
+ public Question(String question, String optionA, String optionB, String optionC, String optionD, String correctAnswer) {
+ this.question = question;
+ this.optionA = optionA;
+ this.optionB = optionB;
+ this.optionC = optionC;
+ this.optionD = optionD;
+ this.correctAnswer = correctAnswer;
+ }
+
+ public String getQuestion() {
+ return question;
+ }
+
+ public String getOptionA() {
+ return optionA;
+ }
+
+ public String getOptionB() {
+ return optionB;
+ }
+
+ public String getOptionC() {
+ return optionC;
+ }
+
+ public String getOptionD() {
+ return optionD;
+ }
+
+ public String getCorrectAnswer() {
+ return correctAnswer;
+ }
+
+ @Override
+ public String toString() {
+ return "Question{" +
+ "question='" + question + '\'' +
+ ", optionA='" + optionA + '\'' +
+ ", optionB='" + optionB + '\'' +
+ ", optionC='" + optionC + '\'' +
+ ", optionD='" + optionD + '\'' +
+ ", correctAnswer='" + correctAnswer + '\'' +
+ '}';
+ }
+}
\ No newline at end of file
diff --git a/src/mathquiz/backend_1/QuizService.java b/src/mathquiz/backend_1/QuizService.java
new file mode 100644
index 0000000..d4dc996
--- /dev/null
+++ b/src/mathquiz/backend_1/QuizService.java
@@ -0,0 +1,298 @@
+package mathquiz.backend;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+import mathquiz.AccountType;
+import mathquiz.Deduplicator;
+import mathquiz.GeneratorFactory;
+import mathquiz.ProblemGenerator;
+
+/**
+ * Quiz Service Class - Handles question generation and quiz logic
+ */
+public class QuizService {
+
+ /**
+ * Generate multiple choice questions
+ */
+ public List generateQuestions(AccountType accountType, int count) {
+ try {
+ // Get question generator
+ ProblemGenerator generator = GeneratorFactory.getGenerator(accountType);
+
+ // Generate original questions
+ List rawQuestions = generator.generate(count);
+
+ // Deduplication processing - use default username if current user is null
+ String username = getCurrentUsername();
+ if (username == null || username.trim().isEmpty()) {
+ username = "default_user";
+ }
+ Deduplicator deduplicator = new Deduplicator(username);
+ List uniqueQuestions = deduplicator.ensureUnique(rawQuestions, count, generator);
+
+ // Convert to multiple choice questions
+ List questions = new ArrayList<>();
+ for (String questionText : uniqueQuestions) {
+ Question question = convertToMultipleChoice(questionText, accountType);
+ questions.add(question);
+ }
+
+ return questions;
+ } catch (Exception e) {
+ System.err.println("Error in generateQuestions: " + e.getMessage());
+ e.printStackTrace();
+ return new ArrayList<>(); // Return empty list instead of null
+ }
+ }
+
+ /**
+ * Convert expression questions to multiple choice questions
+ */
+ private Question convertToMultipleChoice(String expression, AccountType accountType) {
+ try {
+ // Calculate correct answer
+ double correctAnswer = calculateExpression(expression, accountType);
+
+ // Handle invalid answers
+ if (Double.isNaN(correctAnswer) || Double.isInfinite(correctAnswer)) {
+ System.out.println("Invalid answer for expression: " + expression + ", using 0.0");
+ correctAnswer = 0.0;
+ }
+
+ System.out.println("Expression: " + expression + ", Answer: " + correctAnswer);
+
+ // Generate wrong options
+ List options = generateOptions(correctAnswer);
+ System.out.println("Generated " + options.size() + " wrong options: " + options);
+
+ // Randomly arrange options
+ Random random = new Random();
+ String[] optionTexts = new String[4];
+ String correctAnswerText = "";
+
+ // Create a list with correct answer and wrong options
+ List allOptions = new ArrayList<>();
+ allOptions.add(correctAnswer);
+ allOptions.addAll(options);
+
+ System.out.println("All options before shuffle: " + allOptions);
+
+ // Shuffle the options
+ Collections.shuffle(allOptions);
+
+ System.out.println("All options after shuffle: " + allOptions);
+
+ // Find the correct answer index after shuffling
+ int correctAnswerIndex = allOptions.indexOf(correctAnswer);
+ System.out.println("Correct answer index: " + correctAnswerIndex);
+
+ for (int i = 0; i < 4; i++) {
+ optionTexts[i] = formatAnswer(allOptions.get(i));
+ if (i == correctAnswerIndex) {
+ correctAnswerText = getOptionLetter(i);
+ }
+ }
+
+ System.out.println("Final options: " + java.util.Arrays.toString(optionTexts));
+ System.out.println("Correct answer: " + correctAnswerText);
+
+ return new Question(
+ "Calculate: " + expression + " = ?",
+ optionTexts[0], optionTexts[1], optionTexts[2], optionTexts[3],
+ correctAnswerText
+ );
+ } catch (Exception e) {
+ System.err.println("Error in convertToMultipleChoice: " + e.getMessage());
+ e.printStackTrace();
+ // Return a default question
+ return new Question(
+ "Calculate: 1 + 1 = ?",
+ "1", "2", "3", "4",
+ "B"
+ );
+ }
+ }
+
+ /**
+ * Calculate expression result
+ */
+ private double calculateExpression(String expression, AccountType accountType) {
+ try {
+ // Handle special functions
+ String processedExpression = preprocessExpression(expression, accountType);
+
+ // Simple expression calculation (in actual application should use more comprehensive expression parser)
+ return evaluateExpression(processedExpression);
+ } catch (Exception e) {
+ // If calculation fails, return a default value
+ return 0.0;
+ }
+ }
+
+ /**
+ * Preprocess expression, handle special functions
+ */
+ private String preprocessExpression(String expression, AccountType accountType) {
+ String result = expression;
+
+ // Handle square root
+ result = result.replaceAll("sqrt\\(([^)]+)\\)", "Math.sqrt($1)");
+
+ // Handle square
+ result = result.replaceAll("\\(([^)]+)\\)\\^2", "($1) * ($1)");
+
+ // Handle trigonometric functions
+ result = result.replaceAll("sin\\(([^)]+)\\)", "Math.sin($1)");
+ result = result.replaceAll("cos\\(([^)]+)\\)", "Math.cos($1)");
+ result = result.replaceAll("tan\\(([^)]+)\\)", "Math.tan($1)");
+
+ // Handle operators
+ result = result.replace("×", "*");
+ result = result.replace("÷", "/");
+
+ return result;
+ }
+
+ /**
+ * Simple expression calculation
+ */
+ private double evaluateExpression(String expression) {
+ try {
+ // Simplified expression calculation, only handle basic arithmetic operations
+ return evaluateSimpleExpression(expression);
+ } catch (Exception e) {
+ // If calculation fails, return 0
+ return 0.0;
+ }
+ }
+
+ /**
+ * Simplified expression calculation
+ */
+ private double evaluateSimpleExpression(String expression) {
+ // Implement a simple expression calculator here
+ // For simplification, only handle basic number operations
+ try {
+ // Remove all spaces
+ expression = expression.replaceAll("\\s+", "");
+
+ // Handle parentheses
+ while (expression.contains("(")) {
+ int start = expression.lastIndexOf("(");
+ int end = expression.indexOf(")", start);
+ if (end == -1) break;
+
+ String subExpr = expression.substring(start + 1, end);
+ double result = evaluateSimpleExpression(subExpr);
+ expression = expression.substring(0, start) + result + expression.substring(end + 1);
+ }
+
+ // Handle multiplication and division
+ while (expression.contains("*") || expression.contains("/")) {
+ expression = processOperators(expression, new String[]{"*", "/"});
+ }
+
+ // Handle addition and subtraction
+ while (expression.contains("+") || (expression.contains("-") && !expression.startsWith("-"))) {
+ expression = processOperators(expression, new String[]{"+", "-"});
+ }
+
+ return Double.parseDouble(expression);
+ } catch (Exception e) {
+ return 0.0;
+ }
+ }
+
+ /**
+ * Process operators
+ */
+ private String processOperators(String expression, String[] operators) {
+ for (String op : operators) {
+ int index = expression.indexOf(op);
+ if (index > 0) {
+ // Find left operand
+ int leftStart = index - 1;
+ while (leftStart >= 0 && (Character.isDigit(expression.charAt(leftStart)) || expression.charAt(leftStart) == '.')) {
+ leftStart--;
+ }
+ leftStart++;
+
+ // Find right operand
+ int rightEnd = index + 1;
+ while (rightEnd < expression.length() && (Character.isDigit(expression.charAt(rightEnd)) || expression.charAt(rightEnd) == '.')) {
+ rightEnd++;
+ }
+
+ double left = Double.parseDouble(expression.substring(leftStart, index));
+ double right = Double.parseDouble(expression.substring(index + 1, rightEnd));
+ double result = 0;
+
+ switch (op) {
+ case "+": result = left + right; break;
+ case "-": result = left - right; break;
+ case "*": result = left * right; break;
+ case "/": result = right != 0 ? left / right : 0; break;
+ }
+
+ expression = expression.substring(0, leftStart) + result + expression.substring(rightEnd);
+ break;
+ }
+ }
+ return expression;
+ }
+
+ /**
+ * Generate wrong options
+ */
+ private List generateOptions(double correctAnswer) {
+ List options = new ArrayList<>();
+ Random random = new Random();
+
+ // Generate 3 wrong options
+ for (int i = 0; i < 3; i++) {
+ double wrongAnswer;
+ do {
+ // Generate wrong answers near correct answer
+ double variation = (random.nextDouble() - 0.5) * Math.abs(correctAnswer) * 0.5;
+ wrongAnswer = correctAnswer + variation;
+
+ // Ensure wrong answer is not 0 and different from correct answer
+ if (wrongAnswer == 0) {
+ wrongAnswer = random.nextDouble() * 10 + 1;
+ }
+ } while (Math.abs(wrongAnswer - correctAnswer) < 0.01);
+
+ options.add(wrongAnswer);
+ }
+
+ return options;
+ }
+
+ /**
+ * Format answer
+ */
+ private String formatAnswer(double answer) {
+ if (answer == (long) answer) {
+ return String.valueOf((long) answer);
+ } else {
+ return String.format("%.2f", answer);
+ }
+ }
+
+ /**
+ * Get option letter
+ */
+ private String getOptionLetter(int index) {
+ return String.valueOf((char) ('A' + index));
+ }
+
+ /**
+ * Get current username
+ */
+ private String getCurrentUsername() {
+ return mathquiz.gui.QuizSession.getInstance().getCurrentUser();
+ }
+}
\ No newline at end of file
diff --git a/src/mathquiz/backend_1/SimpleEmailSender.java b/src/mathquiz/backend_1/SimpleEmailSender.java
new file mode 100644
index 0000000..4c1c18a
--- /dev/null
+++ b/src/mathquiz/backend_1/SimpleEmailSender.java
@@ -0,0 +1,184 @@
+package mathquiz.backend;
+
+import java.io.*;
+import java.net.*;
+import javax.net.ssl.*;
+
+/**
+ * Simple Email Sender using SMTP protocol
+ * This class provides a basic SMTP client implementation
+ */
+public class SimpleEmailSender {
+
+ private String smtpHost;
+ private int smtpPort;
+ private String username;
+ private String password;
+ private String fromEmail;
+
+ public SimpleEmailSender(String smtpHost, int smtpPort, String username, String password, String fromEmail) {
+ this.smtpHost = smtpHost;
+ this.smtpPort = smtpPort;
+ this.username = username;
+ this.password = password;
+ this.fromEmail = fromEmail;
+ }
+
+ /**
+ * Send email using SMTP protocol with SSL/TLS support
+ */
+ public void sendEmail(String toEmail, String subject, String content) throws Exception {
+ Socket socket = null;
+ BufferedReader reader = null;
+ PrintWriter writer = null;
+
+ try {
+ System.out.println("Connecting to SMTP server: " + smtpHost + ":" + smtpPort);
+
+ // Connect to SMTP server
+ socket = new Socket(smtpHost, smtpPort);
+ reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
+ writer = new PrintWriter(socket.getOutputStream(), true);
+
+ // Read server greeting
+ String response = reader.readLine();
+ System.out.println("Server greeting: " + response);
+ if (!response.startsWith("220")) {
+ throw new Exception("SMTP server error: " + response);
+ }
+
+ // Send EHLO command
+ String hostname = InetAddress.getLocalHost().getHostName();
+ if (hostname == null || hostname.isEmpty()) {
+ hostname = "localhost";
+ }
+ writer.println("EHLO " + hostname);
+ response = reader.readLine();
+ System.out.println("EHLO response: " + response);
+ if (!response.startsWith("250")) {
+ throw new Exception("EHLO failed: " + response);
+ }
+
+ // Read additional EHLO responses
+ while (response.startsWith("250-")) {
+ response = reader.readLine();
+ System.out.println("EHLO continuation: " + response);
+ }
+
+ // Start TLS if supported
+ writer.println("STARTTLS");
+ response = reader.readLine();
+ System.out.println("STARTTLS response: " + response);
+ if (response.startsWith("220")) {
+ // Upgrade to SSL socket
+ SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault();
+ SSLSocket sslSocket = (SSLSocket) factory.createSocket(socket, smtpHost, smtpPort, true);
+ sslSocket.startHandshake();
+
+ // Update streams to use SSL socket
+ reader = new BufferedReader(new InputStreamReader(sslSocket.getInputStream()));
+ writer = new PrintWriter(sslSocket.getOutputStream(), true);
+
+ // Send EHLO again after TLS
+ writer.println("EHLO " + hostname);
+ response = reader.readLine();
+ System.out.println("EHLO after TLS: " + response);
+ if (!response.startsWith("250")) {
+ throw new Exception("EHLO after TLS failed: " + response);
+ }
+
+ // Read additional EHLO responses
+ while (response.startsWith("250-")) {
+ response = reader.readLine();
+ System.out.println("EHLO continuation after TLS: " + response);
+ }
+ }
+
+ // Authenticate using AUTH LOGIN
+ writer.println("AUTH LOGIN");
+ response = reader.readLine();
+ System.out.println("AUTH LOGIN response: " + response);
+ if (!response.startsWith("334")) {
+ throw new Exception("AUTH LOGIN failed: " + response);
+ }
+
+ // Send username (base64 encoded)
+ String encodedUsername = java.util.Base64.getEncoder().encodeToString(username.getBytes());
+ writer.println(encodedUsername);
+ response = reader.readLine();
+ System.out.println("Username auth response: " + response);
+ if (!response.startsWith("334")) {
+ throw new Exception("Username authentication failed: " + response);
+ }
+
+ // Send password (base64 encoded)
+ String encodedPassword = java.util.Base64.getEncoder().encodeToString(password.getBytes());
+ writer.println(encodedPassword);
+ response = reader.readLine();
+ System.out.println("Password auth response: " + response);
+ if (!response.startsWith("235")) {
+ throw new Exception("Password authentication failed: " + response);
+ }
+
+ // Send MAIL FROM
+ writer.println("MAIL FROM:<" + fromEmail + ">");
+ response = reader.readLine();
+ System.out.println("MAIL FROM response: " + response);
+ if (!response.startsWith("250")) {
+ throw new Exception("MAIL FROM failed: " + response);
+ }
+
+ // Send RCPT TO
+ writer.println("RCPT TO:<" + toEmail + ">");
+ response = reader.readLine();
+ System.out.println("RCPT TO response: " + response);
+ if (!response.startsWith("250")) {
+ throw new Exception("RCPT TO failed: " + response);
+ }
+
+ // Send DATA
+ writer.println("DATA");
+ response = reader.readLine();
+ System.out.println("DATA response: " + response);
+ if (!response.startsWith("354")) {
+ throw new Exception("DATA failed: " + response);
+ }
+
+ // Send email headers and content
+ writer.println("From: " + fromEmail);
+ writer.println("To: " + toEmail);
+ writer.println("Subject: " + subject);
+ writer.println("MIME-Version: 1.0");
+ writer.println("Content-Type: text/html; charset=UTF-8");
+ writer.println();
+ writer.println(content);
+ writer.println(".");
+
+ response = reader.readLine();
+ System.out.println("Email send response: " + response);
+ if (!response.startsWith("250")) {
+ throw new Exception("Email sending failed: " + response);
+ }
+
+ // Quit
+ writer.println("QUIT");
+ response = reader.readLine();
+ System.out.println("QUIT response: " + response);
+
+ System.out.println("Email sent successfully to: " + toEmail);
+
+ } catch (Exception e) {
+ System.err.println("Failed to send email: " + e.getMessage());
+ e.printStackTrace();
+ throw e;
+ } finally {
+ try {
+ if (writer != null) writer.close();
+ if (reader != null) reader.close();
+ if (socket != null) socket.close();
+ } catch (IOException e) {
+ // Ignore cleanup errors
+ }
+ }
+ }
+}
diff --git a/src/mathquiz/backend_1/UserService.java b/src/mathquiz/backend_1/UserService.java
new file mode 100644
index 0000000..c518f36
--- /dev/null
+++ b/src/mathquiz/backend_1/UserService.java
@@ -0,0 +1,209 @@
+package mathquiz.backend;
+
+import java.io.*;
+import java.nio.file.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * User Service Class - Handles user registration, login, password management
+ */
+public class UserService {
+ private static final String USERS_FILE = "data/users.txt";
+ private static final String PASSWORDS_FILE = "data/passwords.txt";
+
+ private Map userPasswords;
+ private Map userEmails;
+
+ public UserService() {
+ loadUserData();
+ }
+
+ /**
+ * User registration
+ */
+ public void registerUser(String email, String username) throws IOException {
+ if (userEmails.containsValue(email)) {
+ throw new IllegalArgumentException("This email has already been registered");
+ }
+
+ userEmails.put(username, email);
+
+ // Save user data
+ saveUserData();
+ }
+
+ /**
+ * Set password
+ */
+ public void setPassword(String email, String password) throws IOException {
+ if (!isValidPassword(password)) {
+ throw new IllegalArgumentException("Password does not meet requirements");
+ }
+
+ String username = getUsernameByEmail(email);
+ if (username == null) {
+ throw new IllegalArgumentException("User does not exist");
+ }
+
+ userPasswords.put(username, password);
+ savePasswordData();
+ }
+
+ /**
+ * User login
+ */
+ public boolean login(String email, String password) {
+ String username = getUsernameByEmail(email);
+ if (username == null) {
+ return false;
+ }
+
+ String storedPassword = userPasswords.get(username);
+ if (storedPassword == null) {
+ return false;
+ }
+
+ if (Objects.equals(storedPassword, password)) {
+ // Set current user (use email for session)
+ mathquiz.gui.QuizSession.getInstance().setCurrentUser(email);
+ return true;
+ }
+
+ return false;
+ }
+
+ /**
+ * Change password
+ */
+ public boolean changePassword(String username, String oldPassword, String newPassword) throws IOException {
+ if (!isValidPassword(newPassword)) {
+ throw new IllegalArgumentException("New password does not meet requirements");
+ }
+
+ String storedPassword = userPasswords.get(username);
+ if (!Objects.equals(storedPassword, oldPassword)) {
+ return false;
+ }
+
+ userPasswords.put(username, newPassword);
+ savePasswordData();
+ return true;
+ }
+
+ /**
+ * Validate password format
+ */
+ private boolean isValidPassword(String password) {
+ if (password.length() < 6 || password.length() > 10) {
+ return false;
+ }
+
+ boolean hasUpperCase = false;
+ boolean hasLowerCase = false;
+ boolean hasDigit = false;
+
+ for (char c : password.toCharArray()) {
+ if (Character.isUpperCase(c)) {
+ hasUpperCase = true;
+ } else if (Character.isLowerCase(c)) {
+ hasLowerCase = true;
+ } else if (Character.isDigit(c)) {
+ hasDigit = true;
+ }
+ }
+
+ return hasUpperCase && hasLowerCase && hasDigit;
+ }
+
+ /**
+ * Get username by email
+ */
+ private String getUsernameByEmail(String email) {
+ for (Map.Entry entry : userEmails.entrySet()) {
+ if (entry.getValue().equals(email)) {
+ return entry.getKey();
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Generate username
+ */
+ private String generateUsername(String email) {
+ String baseName = email.split("@")[0];
+ String username = baseName;
+ int counter = 1;
+
+ while (userEmails.containsKey(username)) {
+ username = baseName + counter;
+ counter++;
+ }
+
+ return username;
+ }
+
+ /**
+ * Load user data
+ */
+ private void loadUserData() {
+ userPasswords = new HashMap<>();
+ userEmails = new HashMap<>();
+
+ try {
+ // Create data directory
+ Files.createDirectories(Paths.get("data"));
+
+ // Load user email mapping
+ if (Files.exists(Paths.get(USERS_FILE))) {
+ for (String line : Files.readAllLines(Paths.get(USERS_FILE))) {
+ String[] parts = line.split(",");
+ if (parts.length == 2) {
+ userEmails.put(parts[0], parts[1]);
+ }
+ }
+ }
+
+ // Load user passwords
+ if (Files.exists(Paths.get(PASSWORDS_FILE))) {
+ for (String line : Files.readAllLines(Paths.get(PASSWORDS_FILE))) {
+ String[] parts = line.split(",");
+ if (parts.length == 2) {
+ userPasswords.put(parts[0], parts[1]);
+ }
+ }
+ }
+
+ } catch (IOException e) {
+ // If loading fails, use empty data
+ userPasswords = new HashMap<>();
+ userEmails = new HashMap<>();
+ }
+ }
+
+ /**
+ * Save user data
+ */
+ private void saveUserData() throws IOException {
+ try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(USERS_FILE))) {
+ for (Map.Entry entry : userEmails.entrySet()) {
+ writer.write(entry.getKey() + "," + entry.getValue());
+ writer.newLine();
+ }
+ }
+ }
+
+ /**
+ * Save password data
+ */
+ private void savePasswordData() throws IOException {
+ try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(PASSWORDS_FILE))) {
+ for (Map.Entry entry : userPasswords.entrySet()) {
+ writer.write(entry.getKey() + "," + entry.getValue());
+ writer.newLine();
+ }
+ }
+ }
+}
\ No newline at end of file