package org.ntlab.tampoposerver.services; import org.ntlab.tampoposerver.models.FriendPair; import org.ntlab.tampoposerver.models.FriendRequest; import org.ntlab.tampoposerver.models.User; import org.ntlab.tampoposerver.repositories.FriendRepository; import org.ntlab.tampoposerver.repositories.FriendRequestRepository; import org.ntlab.tampoposerver.repositories.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import javax.annotation.PostConstruct; import java.util.ArrayList; import java.util.Collection; // MEMO: ユーザーのトークンを認証するところはUserRepositoryに任せる // MEMO: フレンド系の操作で認証が必要な場合はここで対応する @Service public class FriendService { private final UserRepository userRepository; private final FriendRepository friendRepository; private final FriendRequestRepository friendRequestRepository; //臨時 @PostConstruct public void init() { // 起動時に test0-test1 のペアをユーザーに紐付ける FriendPair defaultPair = friendRepository.find(0); if (defaultPair != null) { userRepository.addFriendPair(defaultPair.getUser0Id(), defaultPair); userRepository.addFriendPair(defaultPair.getUser1Id(), defaultPair); } System.out.println("Default friend pair (test0 <-> test1) initialized."); } @Autowired public FriendService(UserRepository userRepository, FriendRepository friendRepository, FriendRequestRepository friendRequestRepository) { this.userRepository = userRepository; this.friendRepository = friendRepository; this.friendRequestRepository = friendRequestRepository; } /** * 新しいフレンドリクエストを作成する * * @param token APIリクエストをしてきたユーザーの認証用トークン * @param senderId フレンドリクエストを送ったユーザーのユーザーID * @param receiverId フレンドリクエストを受け取ったユーザーのユーザーID * @return 作成されたフレンドリクエストのインスタンス(tokenに対応したユーザーがsenderIdでもreceiverIdにも関係しない場合は{@code Optional.empty()}) * @apiNote {@code token} が有効かどうか、{@code senderId}と{@code receiverId}に対応したユーザーがそれぞれ存在するかどうかは別に判定が必要 */ public FriendRequest createFriendRequest(String token, String senderId, String receiverId) { User sender = userRepository.getUser(senderId); User receiver = userRepository.getUser(receiverId); if (!sender.getToken().equals(token) && !receiver.getToken().equals(token)) { return null; } return friendRequestRepository.create(new FriendRequest(senderId, receiverId)); } /** * ユーザー自身に関連するフレンドリクエストをすべて返す * * @param token ユーザー認証用のトークン * @return ユーザー自身に関連するすべてのフレンドリクエストのインスタンス(リクエストがなければ空のリスト) * @apiNote {@code token} が有効かどうかは別に判定が必要 */ public ArrayList<FriendRequest> getFriendRequests(String token) { ArrayList<FriendRequest> results = new ArrayList<>(); Collection<FriendRequest> allRequests = friendRequestRepository.findAll(); for (FriendRequest request : allRequests) { User sender = userRepository.getUser(request.getSenderId()); User receiver = userRepository.getUser(request.getReceiverId()); if ((sender.getToken() != null && sender.getToken().equals(token)) || (receiver.getToken() != null && receiver.getToken().equals(token))) { results.add(request); } } return results; } /** * 指定したフレンドリクエストを削除する * * @param token APIリクエストをしてきたユーザーの認証用トークン * @param friendRequestId 削除する対象のフレンドリクエストのID * @return 削除に成功したらtrue, それ以外はfalse * @apiNote {@code token} が有効かどうかは別に判定が必要 */ public boolean removeFriendRequest(String token, int friendRequestId) { FriendRequest targetRequest = friendRequestRepository.find(friendRequestId); if (targetRequest == null) { return false; } User sender = userRepository.getUser(targetRequest.getSenderId()); User receiver = userRepository.getUser(targetRequest.getReceiverId()); if (!sender.getToken().equals(token) && !receiver.getToken().equals(token)) { return false; } return friendRequestRepository.delete(friendRequestId); } /** * 新しくフレンドペアを作成する * * @param user0Id 片方のユーザーのユーザーID * @param user1Id もう一方のユーザーのユーザーID * @return 追加されたフレンドペアのインスタンス(エラーがあった場合は{@code Optional.empty()}) * @apiNote {@code token} が有効かどうかは別に判定が必要 */ public FriendPair createFriendPair(String user0Id, String user1Id) { // フレンドリクエストを検索して削除する FriendRequest acceptedRequest = friendRequestRepository.findAll().stream().filter((req) -> { return (req.getSenderId().equals(user0Id) && req.getReceiverId().equals(user1Id)) || (req.getSenderId().equals(user1Id) && req.getReceiverId().equals(user0Id)); }).findFirst().orElse(null); if (acceptedRequest == null) { return null; } friendRequestRepository.delete(acceptedRequest.getId()); // フレンドを追加する FriendPair createdPair = friendRepository.add(new FriendPair(user0Id, user1Id)); userRepository.addFriendPair(user0Id, createdPair); userRepository.addFriendPair(user1Id, createdPair); return createdPair; } /** * 指定したフレンドのペアを取得する * * @param token APIリクエストをしてきたユーザーの認証用トークン * @param friendPairId 取得する対象のフレンドペアのID * @return 渡したフレンドペアのIDに対応したフレンドペア * @apiNote {@code token} が有効かどうかは別に判定が必要 */ public FriendPair getFriendPair(String token, int friendPairId) { FriendPair foundPair = friendRepository.find(friendPairId); if (foundPair == null) { // System.out.println("FriendPair not found for id: " + friendPairId); return null; } User user0 = userRepository.getUser(foundPair.getUser0Id()); User user1 = userRepository.getUser(foundPair.getUser1Id()); // if (!user0.getToken().equals(token) && !user1.getToken().equals(token)) { // if (!user0.getToken().equals(token) && !user1.getToken().equals(token)) { // System.out.println("Token mismatch! Provided: " + token); // System.out.println("user0 token: " + user0.getToken()); // System.out.println("user1 token: " + user1.getToken()); // return null; // } // System.out.println("Token valid, returning pair"); // return null; // } return foundPair; } /** * 指定したフレンドのペアを削除する * * @param token APIリクエストをしてきたユーザーの認証用トークン * @param friendPairId 削除する対象のフレンドペアのID * @return 削除に成功したらtrue, それ以外はfalse */ public boolean removeFriendPair(String token, int friendPairId) { FriendPair foundPair = friendRepository.find(friendPairId); if (foundPair == null) { return false; } User user0 = userRepository.getUser(foundPair.getUser0Id()); User user1 = userRepository.getUser(foundPair.getUser1Id()); if (!user0.getToken().equals(token) && !user1.getToken().equals(token)) { return false; } // フレンドペアを削除する return friendRepository.delete(friendPairId) && userRepository.deleteFriendPair(user0.getUserId(), foundPair) && userRepository.deleteFriendPair(user1.getUserId(), foundPair); } /** * ユーザーIDが{@code userId}のユーザーとフレンドになっているユーザーのIDをすべて返す * * @param token APIリクエストをしてきたユーザーの認証用トークン * @param userId APIリクエストをしてきたユーザーのID * @return ユーザーIDが {@code userId} のユーザーとフレンドになっているユーザーすべてのID * @apiNote ペアがない場合は空の配列、トークンとユーザーIDで認証できなければnullを返す */ public ArrayList<String> getFriendIds(String token, String userId) { User user = userRepository.getUser(userId); if (user == null || !user.getToken().equals(token)) { return null; } ArrayList<String> friendIds = new ArrayList<>(); for (FriendPair friendPair : user.getFriendPairs()) { if (friendPair.getUser0Id().equals(user.getUserId())) { friendIds.add(friendPair.getUser1Id()); } else { friendIds.add(friendPair.getUser0Id()); } } return friendIds; } }