package org.aegee.runanddine.pathfinder.assignmentbuilding;

import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.aegee.runanddine.pathfinder.OptGroup;

/**
 * Validates course assignments
 */
class GroupsAndAssignmentValidator {

    /**
     * Validate course assignments
     * @param optGroups List of all OptGroups to be validated
     * @param map Map to access OptGroups by ID
     * @return List of error messages
     */
    static List<String> validate(Collection<OptGroup> optGroups, Map<Integer, OptGroup> map) {
        
        List<String> errors = new LinkedList<String>();
        for (OptGroup group : optGroups) {
            List<Integer> hasSeen = new LinkedList<Integer>();

            OptGroup group1 = map.get(group.getOtherId1());
            OptGroup group2 = map.get(group.getOtherId2());
            OptGroup guest1 = map.get(group.getGuest1());
            OptGroup guest2 = map.get(group.getGuest2());

            hasSeen.add(group.getOtherId1());
            
            if (hasSeen.contains(group.getOtherId2()) &  hasSeen.add(group.getOtherId2())) {
                errors.add("Group" + group.getAbstractId() + " sees group" + group2.getAbstractId() + " at least twice");
            }
                    
            if (hasSeen.contains(group.getGuest1()) & hasSeen.add(group.getGuest1())) {
                errors.add("Group" + group.getAbstractId() + " sees group" + guest1.getAbstractId() + " at least twice");
            }
            
            if (hasSeen.contains(group.getGuest2()) & hasSeen.add(group.getGuest2())) {
                errors.add("Group" + group.getAbstractId() + " sees group" + guest2.getAbstractId() + " at least twice");
            }
            if (group1.getGuest1() != group.getId() & hasSeen.contains(group1.getGuest1()) & hasSeen.add(group1.getGuest1())) {
                errors.add("Group" + group.getAbstractId() + " sees group" + map.get(group1.getGuest1()).getAbstractId() + " at least twice");
            }
            if (group1.getGuest2() != group.getId() & hasSeen.contains(group1.getGuest2()) & hasSeen.add(group1.getGuest2())) {
                errors.add("Group" + group.getAbstractId() + " sees group" + map.get(group1.getGuest2()).getAbstractId() + " at least twice");
            }
            if (group2.getGuest1() != group.getId() & hasSeen.contains(group2.getGuest1()) & hasSeen.add(group2.getGuest1())) {
                errors.add("Group" + group.getAbstractId() + " sees group" + map.get(group2.getGuest1()).getAbstractId() + " at least twice");
            }
            if (group2.getGuest2() != group.getId() & hasSeen.contains(group2.getGuest2()) & hasSeen.add(group2.getGuest2())) {
                errors.add("Group" + group.getAbstractId() + " sees group" + map.get(group2.getGuest2()).getAbstractId() + " at least twice");
            }
            if (group.getOtherCourse1() != group1.getCourse()) {
                errors.add("Group" + group1.getAbstractId() + " does not prepare the course that group" + group.getAbstractId() + " is expecting");
            }
            if (group.getOtherCourse2() != group2.getCourse()) {
                errors.add("Group" + group2.getAbstractId() + " does not prepare the course that group" + group.getAbstractId() + " is expecting");
            }
            if (map.get(group.getGuest1()).getCourse() == group.getCourse()) {
                errors.add("Group" + guest1.getAbstractId() + " is preparing the same course as group" + group.getAbstractId());
            }
            if (map.get(group.getGuest2()).getCourse() == group.getCourse()) {
                errors.add("Group" + guest2.getAbstractId() + " is preparing the same course as group" + group.getAbstractId());
            }
        }
        return errors;
    }
}