package fr.ippon.tatami.service;
import fr.ippon.tatami.domain.User;
import fr.ippon.tatami.domain.status.MentionFriend;
import fr.ippon.tatami.repository.*;
import fr.ippon.tatami.security.AuthenticationService;
import fr.ippon.tatami.service.util.DomainUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import javax.inject.Inject;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* Manages the user's frienships.
* <p/>
* - A friend is someone you follow
* - A follower is someone that follows you
*
* @author Julien Dubois
*/
@Service
public class FriendshipService {
private final Logger log = LoggerFactory.getLogger(FriendshipService.class);
@Inject
private UserRepository userRepository;
@Inject
private FollowerRepository followerRepository;
@Inject
private FriendRepository friendRepository;
@Inject
private CounterRepository counterRepository;
@Inject
private StatusRepository statusRepository;
@Inject
private MentionlineRepository mentionlineRepository;
@Inject
private AuthenticationService authenticationService;
/**
* Follow a user.
*
* @return true if the operation succeeds, false otherwise
*/
public boolean followUser(String usernameToFollow) {
log.debug("Following user : {}", usernameToFollow);
User currentUser = authenticationService.getCurrentUser();
String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());
String loginToFollow = DomainUtil.getLoginFromUsernameAndDomain(usernameToFollow, domain);
User followedUser = userRepository.findUserByLogin(loginToFollow);
if (followedUser != null && !followedUser.equals(currentUser)) {
if (counterRepository.getFriendsCounter(currentUser.getLogin()) > 0) {
for (String alreadyFollowingTest : friendRepository.findFriendsForUser(currentUser.getLogin())) {
if (alreadyFollowingTest.equals(loginToFollow)) {
log.debug("User {} already follows user {}", currentUser.getLogin(), followedUser.getLogin());
return false;
}
}
}
friendRepository.addFriend(currentUser.getLogin(), followedUser.getLogin());
counterRepository.incrementFriendsCounter(currentUser.getLogin());
followerRepository.addFollower(followedUser.getLogin(), currentUser.getLogin());
counterRepository.incrementFollowersCounter(followedUser.getLogin());
// mention the friend that the user has started following him
MentionFriend mentionFriend = statusRepository.createMentionFriend(followedUser.getLogin(), currentUser.getLogin());
mentionlineRepository.addStatusToMentionline(mentionFriend.getLogin(), mentionFriend.getStatusId());
log.debug("User {} now follows user {} ", currentUser.getLogin(), followedUser.getLogin());
return true;
} else {
log.debug("Followed user does not exist : " + loginToFollow);
return false;
}
}
/**
* Un-follow a user.
*
* @return true if the operation succeeds, false otherwise
*/
public boolean unfollowUser(String usernameToUnfollow) {
log.debug("Removing followed user : {}", usernameToUnfollow);
User currentUser = authenticationService.getCurrentUser();
String loginToUnfollow = this.getLoginFromUsername(usernameToUnfollow);
User userToUnfollow = userRepository.findUserByLogin(loginToUnfollow);
return unfollowUser(currentUser, userToUnfollow);
}
/**
* Un-follow a user.
*
* @return true if the operation succeeds, false otherwise
*/
public boolean unfollowUser(User currentUser, User userToUnfollow) {
if (userToUnfollow != null) {
String loginToUnfollow = userToUnfollow.getLogin();
boolean userAlreadyFollowed = false;
for (String alreadyFollowingTest : friendRepository.findFriendsForUser(currentUser.getLogin())) {
if (alreadyFollowingTest.equals(loginToUnfollow)) {
userAlreadyFollowed = true;
}
}
if (userAlreadyFollowed) {
friendRepository.removeFriend(currentUser.getLogin(), loginToUnfollow);
counterRepository.decrementFriendsCounter(currentUser.getLogin());
followerRepository.removeFollower(loginToUnfollow, currentUser.getLogin());
counterRepository.decrementFollowersCounter(loginToUnfollow);
log.debug("User {} has stopped following user {}", currentUser.getLogin(), loginToUnfollow);
return true;
} else {
return false;
}
} else {
log.debug("Followed user does not exist.");
return false;
}
}
public List<String> getFriendIdsForUser(String login) {
log.debug("Retrieving friends for user : {}", login);
return friendRepository.findFriendsForUser(login);
}
public Collection<String> getFollowerIdsForUser(String login) {
log.debug("Retrieving followed users : {}", login);
return followerRepository.findFollowersForUser(login);
}
public Collection<User> getFriendsForUser(String username) {
String login = this.getLoginFromUsername(username);
Collection<String> friendLogins = friendRepository.findFriendsForUser(login);
Collection<User> friends = new ArrayList<User>();
for (String friendLogin : friendLogins) {
User friend = userRepository.findUserByLogin(friendLogin);
friends.add(friend);
}
return friends;
}
public Collection<User> getFollowersForUser(String username) {
String login = this.getLoginFromUsername(username);
Collection<String> followersLogins = followerRepository.findFollowersForUser(login);
Collection<User> followers = new ArrayList<User>();
for (String followerLogin : followersLogins) {
User follower = userRepository.findUserByLogin(followerLogin);
followers.add(follower);
}
return followers;
}
/**
* Finds if the "userLogin" user is followed by the current user.
*/
public boolean isFollowed(String userLogin) {
log.debug("Retrieving if you follow this user : {}", userLogin);
boolean isFollowed = false;
User user = authenticationService.getCurrentUser();
if (null != user && !userLogin.equals(user.getLogin())) {
Collection<String> users = getFollowerIdsForUser(userLogin);
if (null != users && users.size() > 0) {
for (String follower : users) {
if (follower.equals(user.getLogin())) {
isFollowed = true;
break;
}
}
}
}
return isFollowed;
}
/**
* Finds if the current user user follow the "userLogin".
*/
public boolean isFollowing(String userLogin) {
log.debug("Retrieving if you follow this user : {}", userLogin);
boolean isFollowing = false;
User user = authenticationService.getCurrentUser();
if (null != user && !userLogin.equals(user.getLogin())) {
Collection<User> users = getFriendsForUser(user.getUsername());
if (null != users && users.size() > 0) {
for (User follower : users) {
if (follower.getUsername().equals(userLogin)) {
isFollowing = true;
break;
}
}
}
}
return isFollowing;
}
private String getLoginFromUsername(String username) {
User currentUser = authenticationService.getCurrentUser();
String domain = DomainUtil.getDomainFromLogin(currentUser.getLogin());
return DomainUtil.getLoginFromUsernameAndDomain(username, domain);
}
}