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 UsersRepositoryImpl implements UsersRepositoryCustom {

    @Autowired
    private UsersRepository usersRepository;
    
    @Autowired
    private GroupsRepository groupsRepository;
    
    @Override
    // TODO: implement a transaction mecanism...
    public void setGroupsList(User user, Collection<String> groupIds) {
        
        assert groupIds != null : "list of group ids must not be null";
        
        // takes previous user list
        List<String> oldGroups = new ArrayList<>(user.getGroups());
        
        // calculate difference between two list
        List<String> groupIdDel =  new ArrayList<>(oldGroups);
        groupIdDel.removeAll(groupIds);
        
        List<String> groupIdAdd = new ArrayList<>(groupIds);
        groupIdAdd.removeAll(oldGroups);
        
        List<Group> groupAdd = IteratorUtils.toList(this.groupsRepository.findAll(groupIdAdd).iterator());
        for (Group group : groupAdd) {
            group.addUser(user);
        }
        this.groupsRepository.save(groupAdd);
        List<Group> groupDel = IteratorUtils.toList(this.groupsRepository.findAll(groupIdDel).iterator());
        for (Group group : groupDel) {
            group.removeUser(user);
        }
        this.groupsRepository.save(groupDel);
        
        user.getGroups().clear();
        user.getGroups().addAll(groupIds);
        
        this.usersRepository.save(user);
    }

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

}
