package org.iri_research.renkan.repositories;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.collections4.IteratorUtils;
import org.iri_research.renkan.models.Group;
import org.iri_research.renkan.models.User;
import org.springframework.beans.factory.annotation.Autowired;

public class GroupsRepositoryImpl implements GroupsRepositoryCustom {

    @Autowired
    private UsersRepository usersRepository;
    
    @Autowired
    private GroupsRepository groupsRepository;
    
    @Override
    // TODO: implement a transaction mecanism...
    public void setUsersList(Group group, Collection<String> userIds) {
        
        assert userIds != null : "list of user ids must not be null";
        
        // takes previous user list
        List<String> oldUsers = new ArrayList<>(group.getUsers());
        
        // calculate difference between two list
        List<String> userIdDel =  new ArrayList<>(oldUsers);
        userIdDel.removeAll(userIds);
        
        List<String> userIdAdd = new ArrayList<>(userIds);
        userIdAdd.removeAll(oldUsers);
        
        List<User> userAdd = IteratorUtils.toList(this.usersRepository.findAll(userIdAdd).iterator());
        for (User user : userAdd) {
            user.addGroup(group.getId());
        }
        this.usersRepository.save(userAdd);
        List<User> userDel = IteratorUtils.toList(this.usersRepository.findAll(userIdDel).iterator());
        for (User user : userDel) {
            user.removeGroup(group.getId());
        }
        this.usersRepository.save(userDel);
        
        group.getUsers().clear();
        group.getUsers().addAll(userIds);
        
        this.groupsRepository.save(group);
    }

    @Override
    public Map<String, User> getUsersMap(Group group) {
        HashMap<String, User> res = new HashMap<>(group.getUsers().size());
        
        for (User user : this.usersRepository.findAll(group.getUsers())) {
            res.put(user.getId(), user);
        }
        
        return res;
    }

}
