package com.rit.whatsapp.service; import com.rit.whatsapp.model.UserEntity; import com.rit.whatsapp.model.UserState; import com.rit.whatsapp.repository.UserRepository; import com.rit.whatsapp.util.EncryptionUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.Map; import java.util.Optional; import java.util.concurrent.ConcurrentHashMap; @Service public class SessionService { private final Map userStates = new ConcurrentHashMap<>(); // In-memory cache for API session tokens private final Map sessionTokens = new ConcurrentHashMap<>(); private final Map temporaryLoginIds = new ConcurrentHashMap<>(); private final Map studentNames = new ConcurrentHashMap<>(); private final UserRepository userRepository; private final EncryptionUtils encryptionUtils; private final ImsApiService imsApiService; @Autowired public SessionService(UserRepository userRepository, EncryptionUtils encryptionUtils, ImsApiService imsApiService) { this.userRepository = userRepository; this.encryptionUtils = encryptionUtils; this.imsApiService = imsApiService; } public UserState getUserState(String phoneNumber) { return userStates.getOrDefault(phoneNumber, UserState.MAIN_MENU); } public void setUserState(String phoneNumber, UserState state) { userStates.put(phoneNumber, state); } public void resetState(String phoneNumber) { userStates.remove(phoneNumber); } public boolean isAuthenticated(String phoneNumber) { if (sessionTokens.containsKey(phoneNumber)) { return true; } // Check database for persistent session Optional userOpt = userRepository.findById(phoneNumber); if (userOpt.isPresent()) { UserEntity user = userOpt.get(); String decryptedPasscode = encryptionUtils.decrypt(user.getEncryptedPasscode()); // Silent background login String token = imsApiService.authenticate(user.getImsId(), decryptedPasscode); if (token != null) { sessionTokens.put(phoneNumber, token); return true; } } return false; } public void authenticateUser(String phoneNumber, String imsId, String passcode, String token) { sessionTokens.put(phoneNumber, token); // Persist to database String encryptedPasscode = encryptionUtils.encrypt(passcode); UserEntity user = new UserEntity(phoneNumber, imsId, encryptedPasscode); userRepository.save(user); } public String getImsToken(String phoneNumber) { // Ensure they are authenticated (which populates the token cache if needed) if (isAuthenticated(phoneNumber)) { return sessionTokens.get(phoneNumber); } return null; } public void logoutUser(String phoneNumber) { String token = sessionTokens.remove(phoneNumber); if (token != null) { imsApiService.logout(token); } userRepository.deleteById(phoneNumber); studentNames.remove(phoneNumber); resetState(phoneNumber); } public String getStudentName(String phoneNumber, String token) { if (studentNames.containsKey(phoneNumber)) { return studentNames.get(phoneNumber); } String name = imsApiService.getStudentName(token); studentNames.put(phoneNumber, name); return name; } public void setTempLoginId(String phoneNumber, String tempId) { temporaryLoginIds.put(phoneNumber, tempId); } public String getTempLoginId(String phoneNumber) { return temporaryLoginIds.get(phoneNumber); } public void clearTempLoginId(String phoneNumber) { temporaryLoginIds.remove(phoneNumber); } }