/**
 * Copyright (C) 2019 Patrik Dufresne Service Logiciel <info@patrikdufresne.com>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
package com.planimod.core;

import static com.planimod.core.TimeUtils.time;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

import java.util.AbstractMap;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

import com.patrikdufresne.managers.ManagerException;
import com.patrikdufresne.util.BidiMultiMap;

/**
 * This test case is used to perform unit test on the {@link TaskManager} .
 * 
 * @author Patrik Dufresne
 * 
 */
public class TaskManagerTest extends ManagerTestCase {

    private ShiftUtils shifts;

    @Test
    public void createPlanif_WithProductionEvent() {

        /*
         * Here the scenario : 6h-16h, lun, mar, mer, jeu - product#1
         */
        Product p1 = addProduct(managers, "product1");

        // Add production event
        ProductionEvent event1 = addProductionEvent(managers, p1, shifts.monDay);
        // event1.setStartDate(time("Mon 6:00"));
        // event1.setEndDate(time("Mon 16:00"));
        // event1.setCalendarEntry(planif);
        // event1.setProduct(p1);

        ProductionEvent event2 = addProductionEvent(managers, p1, shifts.tueDay);
        // event2.setStartDate(time("Tue 6:00"));
        // event2.setEndDate(time("Tue 16:00"));
        // event2.setCalendarEntry(planif);
        // event2.setProduct(p1);

        ProductionEvent event3 = addProductionEvent(managers, p1, shifts.wedDay);
        // event3.setStartDate(time("Wed 6:00"));
        // event3.setEndDate(time("Wed 16:00"));
        // event3.setCalendarEntry(planif);
        // event3.setProduct(p1);

        ProductionEvent event4 = addProductionEvent(managers, p1, shifts.thuDay);
        // event4.setStartDate(time("Thu 6:00"));
        // event4.setEndDate(time("Thu 16:00"));
        // event4.setCalendarEntry(planif);
        // event4.setProduct(p1);

        List<ProductionEvent> events;
        try {
            events = managers.getProductionEventManager().list(time("Mon 0:00"), time("Fri 0:00"));
        } catch (ManagerException e) {
            fail("Error listing events", e);
            return;
        }

        assertEquals("Wrong number of events", 4, events.size());
        assertTrue("Event1 not found", events.contains(event1));
        assertTrue("Event2 not found", events.contains(event2));
        assertTrue("Event3 not found", events.contains(event3));
        assertTrue("Event4 not found", events.contains(event4));

    }

    /**
     * Create the required shifts.
     */
    @Before
    public void createShifts() {
        shifts = new ShiftUtils();
        shifts.addShifts(managers);
        shifts.addExtendedShifts(managers);
    }

    @Test
    public void GetNonAvailabilityTable() throws ManagerException {

        // Create products - positions
        Section section = addSection(managers, "section");
        Product product = addProduct(managers, "product#1");
        Position pos1 = addPosition(managers, section, "position1", false);
        Position pos2 = addPosition(managers, section, "position2", false);
        Position pos3 = addPosition(managers, section, "position3", false);
        Position pos4 = addPosition(managers, section, "position4", false);
        Position pos5 = addPosition(managers, section, "position5", false);
        addProductPosition(managers, product, pos1, 1);
        addProductPosition(managers, product, pos2, 1);
        addProductPosition(managers, product, pos3, 1);
        addProductPosition(managers, product, pos4, 1);
        addProductPosition(managers, product, pos5, 1);

        // Create planif
        ProductionEvent event1 = addProductionEvent(managers, product, shifts.monDay);

        Task t1 = addTask(managers, event1, pos1, null, null);
        Task t2 = addTask(managers, event1, pos2, null, null);
        Task t3 = addTask(managers, event1, pos3, null, null);
        Task t4 = addTask(managers, event1, pos4, null, null);
        Task t5 = addTask(managers, event1, pos5, null, null);

        // Create qualify employee
        Employee emp1 = addEmployee(managers, "employee#1");
        addQualification(managers, emp1, pos1, pos3, pos5);
        addNonAvailability(managers, emp1, shifts.monDay.getStartDate(), shifts.monDay.getEndDate());
        Employee emp2 = addEmployee(managers, "employee#2");
        addQualification(managers, emp2, pos2, pos4);
        Employee emp3 = addEmployee(managers, "employee#3");
        addQualification(managers, emp3, pos1, pos4, pos5);
        Employee emp4 = addEmployee(managers, "employee#4");

        BidiMultiMap<Employee, Task> table = managers.getTaskManager().getNonAvailabilityTable(shifts.monDay.getStartDate(), shifts.monDay.getEndDate());

        assertEquals(5, table.size());
        assertEquals(1, table.keySet().size());
        assertEquals(5, table.valueSet().size());

        assertTrue(table.keySet().contains(emp1));

        assertTrue(table.valueSet(emp1).contains(t1));
        assertTrue(table.valueSet(emp1).contains(t2));
        assertTrue(table.valueSet(emp1).contains(t3));
        assertTrue(table.valueSet(emp1).contains(t4));
        assertTrue(table.valueSet(emp1).contains(t5));

        assertFalse(table.keySet().contains(emp2));
        assertFalse(table.keySet().contains(emp3));
        assertFalse(table.keySet().contains(emp4));

    }

    /**
     * Check if the non availability table does not contains archived employee.
     * 
     * @throws ManagerException
     */
    @Test
    public void GetNonAvailabilityTable_WithArchivedEmployee() throws ManagerException {

        // Create products - positions
        Section section = addSection(managers, "section");
        Product product = addProduct(managers, "product#1");
        Position pos1 = addPosition(managers, section, "position1", false);
        Position pos2 = addPosition(managers, section, "position2", false);
        Position pos3 = addPosition(managers, section, "position3", false);
        Position pos4 = addPosition(managers, section, "position4", false);
        Position pos5 = addPosition(managers, section, "position5", false);
        addProductPosition(managers, product, pos1, 1);
        addProductPosition(managers, product, pos2, 1);
        addProductPosition(managers, product, pos3, 1);
        addProductPosition(managers, product, pos4, 1);
        addProductPosition(managers, product, pos5, 1);

        // Create planif
        ProductionEvent event1 = addProductionEvent(managers, product, shifts.monDay);

        Task t1 = addTask(managers, event1, pos1, null, null);
        Task t2 = addTask(managers, event1, pos2, null, null);
        Task t3 = addTask(managers, event1, pos3, null, null);
        Task t4 = addTask(managers, event1, pos4, null, null);
        Task t5 = addTask(managers, event1, pos5, null, null);

        // Create qualify employee
        Employee emp1 = addEmployee(managers, "employee#1");
        addQualification(managers, emp1, pos1, pos3, pos5);
        addNonAvailability(managers, emp1, shifts.monDay.getStartDate(), shifts.monDay.getEndDate());
        Employee emp2 = addEmployee(managers, "employee#2");
        addQualification(managers, emp2, pos2, pos4);
        Employee emp3 = addEmployee(managers, "employee#3");
        addQualification(managers, emp3, pos1, pos4, pos5);
        Employee emp4 = addEmployee(managers, "employee#4");
        addQualification(managers, emp4, pos1, pos2, pos5);
        addNonAvailability(managers, emp4, shifts.monDay.getStartDate(), shifts.monDay.getEndDate());

        // Archive employee
        managers.archiveAll(Arrays.asList(emp4));

        BidiMultiMap<Employee, Task> table = managers.getTaskManager().getNonAvailabilityTable(shifts.monDay.getStartDate(), shifts.monDay.getEndDate());

        assertEquals(5, table.size());
        assertEquals(1, table.keySet().size());
        assertEquals(5, table.valueSet().size());

        assertTrue(table.keySet().contains(emp1));

        assertTrue(table.valueSet(emp1).contains(t1));
        assertTrue(table.valueSet(emp1).contains(t2));
        assertTrue(table.valueSet(emp1).contains(t3));
        assertTrue(table.valueSet(emp1).contains(t4));
        assertTrue(table.valueSet(emp1).contains(t5));

        assertFalse(table.keySet().contains(emp4));

    }

    /**
     * Check if the function getQualificationTable is returning the expected results.
     * 
     * @throws ManagerException
     */
    @Test
    public void GetQualificationTable() throws ManagerException {

        // Create products - positions
        Section section = addSection(managers, "section");
        Product product = addProduct(managers, "product#1");
        Position pos1 = addPosition(managers, section, "position1", false);
        Position pos2 = addPosition(managers, section, "position2", false);
        Position pos3 = addPosition(managers, section, "position3", false);
        Position pos4 = addPosition(managers, section, "position4", false);
        Position pos5 = addPosition(managers, section, "position5", false);
        addProductPosition(managers, product, pos1, 1);
        addProductPosition(managers, product, pos2, 1);
        addProductPosition(managers, product, pos3, 1);
        addProductPosition(managers, product, pos4, 1);
        addProductPosition(managers, product, pos5, 1);

        // Create planif

        ProductionEvent event1 = addProductionEvent(managers, product, shifts.monDay);

        Task t1 = addTask(managers, event1, pos1, null, null);
        Task t2 = addTask(managers, event1, pos2, null, null);
        Task t3 = addTask(managers, event1, pos3, null, null);
        Task t4 = addTask(managers, event1, pos4, null, null);
        Task t5 = addTask(managers, event1, pos5, null, null);

        // Create qualify employee
        Employee emp1 = addEmployee(managers, "employee#1");
        addQualification(managers, emp1, pos1, pos3, pos5);
        Employee emp2 = addEmployee(managers, "employee#2");
        addQualification(managers, emp2, pos2, pos4);
        Employee emp3 = addEmployee(managers, "employee#3");
        addQualification(managers, emp3, pos1, pos4, pos5);
        Employee emp4 = addEmployee(managers, "employee#4");

        BidiMultiMap<Employee, Task> table = managers.getTaskManager().getQualificationTable(shifts.monDay.getStartDate(), shifts.monDay.getEndDate());

        assertEquals(8, table.size());
        assertEquals(3, table.keySet().size());
        assertEquals(5, table.valueSet().size());

        assertTrue(table.containsKey(emp1));
        assertTrue(table.containsKey(emp2));
        assertTrue(table.containsKey(emp3));
        assertFalse(table.containsKey(emp4));

        assertTrue(table.containsValue(t1));
        assertTrue(table.containsValue(t2));
        assertTrue(table.containsValue(t3));
        assertTrue(table.containsValue(t4));
        assertTrue(table.containsValue(t5));

        assertTrue(table.containsEntry(emp1, t1));
        assertFalse(table.containsEntry(emp1, t2));
        assertTrue(table.containsEntry(emp1, t3));
        assertFalse(table.containsEntry(emp1, t4));
        assertTrue(table.containsEntry(emp1, t5));

        assertFalse(table.containsEntry(emp2, t1));
        assertTrue(table.containsEntry(emp2, t2));
        assertFalse(table.containsEntry(emp2, t3));
        assertTrue(table.containsEntry(emp2, t4));
        assertFalse(table.containsEntry(emp2, t5));

        assertTrue(table.containsEntry(emp3, t1));
        assertFalse(table.containsEntry(emp3, t2));
        assertFalse(table.containsEntry(emp3, t3));
        assertTrue(table.containsEntry(emp3, t4));
        assertTrue(table.containsEntry(emp3, t5));

        assertEquals(8, table.entrySet().size());

        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp1, t1)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp1, t2)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp1, t3)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp1, t4)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp1, t5)));

        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp2, t1)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp2, t2)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp2, t3)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp2, t4)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp2, t5)));

        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp3, t1)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp3, t2)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp3, t3)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp3, t4)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp3, t5)));

        assertTrue(table.keySet().contains(emp1));
        assertTrue(table.keySet().contains(emp2));
        assertTrue(table.keySet().contains(emp3));
        assertFalse(table.keySet().contains(emp4));

        assertTrue(table.valueSet().contains(t1));
        assertTrue(table.valueSet().contains(t2));
        assertTrue(table.valueSet().contains(t3));
        assertTrue(table.valueSet().contains(t4));
        assertTrue(table.valueSet().contains(t5));

        assertTrue(table.valueSet(emp1).contains(t1));
        assertFalse(table.valueSet(emp1).contains(t2));
        assertTrue(table.valueSet(emp1).contains(t3));
        assertFalse(table.valueSet(emp1).contains(t4));
        assertTrue(table.valueSet(emp1).contains(t5));

        assertFalse(table.valueSet(emp2).contains(t1));
        assertTrue(table.valueSet(emp2).contains(t2));
        assertFalse(table.valueSet(emp2).contains(t3));
        assertTrue(table.valueSet(emp2).contains(t4));
        assertFalse(table.valueSet(emp2).contains(t5));

        assertTrue(table.valueSet(emp3).contains(t1));
        assertFalse(table.valueSet(emp3).contains(t2));
        assertFalse(table.valueSet(emp3).contains(t3));
        assertTrue(table.valueSet(emp3).contains(t4));
        assertTrue(table.valueSet(emp3).contains(t5));

        assertTrue(table.keySet(t1).contains(emp1));
        assertFalse(table.keySet(t1).contains(emp2));
        assertTrue(table.keySet(t1).contains(emp3));
        assertFalse(table.keySet(t1).contains(emp4));

        assertFalse(table.keySet(t2).contains(emp1));
        assertTrue(table.keySet(t2).contains(emp2));
        assertFalse(table.keySet(t2).contains(emp3));
        assertFalse(table.keySet(t2).contains(emp4));

        assertTrue(table.keySet(t3).contains(emp1));
        assertFalse(table.keySet(t3).contains(emp2));
        assertFalse(table.keySet(t3).contains(emp3));
        assertFalse(table.keySet(t3).contains(emp4));

        assertFalse(table.keySet(t4).contains(emp1));
        assertTrue(table.keySet(t4).contains(emp2));
        assertTrue(table.keySet(t4).contains(emp3));
        assertFalse(table.keySet(t4).contains(emp4));

        assertTrue(table.keySet(t5).contains(emp1));
        assertFalse(table.keySet(t5).contains(emp2));
        assertTrue(table.keySet(t5).contains(emp3));
        assertFalse(table.keySet(t5).contains(emp4));

    }

    /**
     * Check if the qualification table does not include the
     * 
     * @throws ManagerException
     */
    @Test
    public void getQualificationTable_WithArchivedEmployee() throws ManagerException {

        // Create products - positions
        Section section = addSection(managers, "section");
        Product product = addProduct(managers, "product#1");
        Position pos1 = addPosition(managers, section, "position1", false);
        Position pos2 = addPosition(managers, section, "position2", false);
        Position pos3 = addPosition(managers, section, "position3", false);
        Position pos4 = addPosition(managers, section, "position4", false);
        Position pos5 = addPosition(managers, section, "position5", false);
        addProductPosition(managers, product, pos1, 1);
        addProductPosition(managers, product, pos2, 1);
        addProductPosition(managers, product, pos3, 1);
        addProductPosition(managers, product, pos4, 1);
        addProductPosition(managers, product, pos5, 1);

        // Create planif
        ProductionEvent event1 = addProductionEvent(managers, product, shifts.monDay);

        Task t1 = addTask(managers, event1, pos1, null, null);
        Task t2 = addTask(managers, event1, pos2, null, null);
        Task t3 = addTask(managers, event1, pos3, null, null);
        Task t4 = addTask(managers, event1, pos4, null, null);
        Task t5 = addTask(managers, event1, pos5, null, null);

        // Create qualify employee
        Employee emp1 = addEmployee(managers, "employee#1");
        addQualification(managers, emp1, pos1, pos3, pos5);
        Employee emp2 = addEmployee(managers, "employee#2");
        addQualification(managers, emp2, pos2, pos4);
        Employee emp3 = addEmployee(managers, "employee#3");
        addQualification(managers, emp3, pos1, pos4, pos5);
        Employee emp4 = addEmployee(managers, "employee#4");
        addQualification(managers, emp4, pos1, pos2, pos5);

        // Archive employee
        managers.archiveAll(Arrays.asList(emp4));

        BidiMultiMap<Employee, Task> table = managers.getTaskManager().getQualificationTable(shifts.monDay.getStartDate(), shifts.monDay.getEndDate());

        assertEquals(8, table.size());
        assertEquals(3, table.keySet().size());
        assertEquals(5, table.valueSet().size());

        assertTrue(table.containsKey(emp1));
        assertTrue(table.containsKey(emp2));
        assertTrue(table.containsKey(emp3));
        assertFalse(table.containsKey(emp4));

        assertTrue(table.containsValue(t1));
        assertTrue(table.containsValue(t2));
        assertTrue(table.containsValue(t3));
        assertTrue(table.containsValue(t4));
        assertTrue(table.containsValue(t5));

        assertTrue(table.containsEntry(emp1, t1));
        assertFalse(table.containsEntry(emp1, t2));
        assertTrue(table.containsEntry(emp1, t3));
        assertFalse(table.containsEntry(emp1, t4));
        assertTrue(table.containsEntry(emp1, t5));

        assertFalse(table.containsEntry(emp2, t1));
        assertTrue(table.containsEntry(emp2, t2));
        assertFalse(table.containsEntry(emp2, t3));
        assertTrue(table.containsEntry(emp2, t4));
        assertFalse(table.containsEntry(emp2, t5));

        assertTrue(table.containsEntry(emp3, t1));
        assertFalse(table.containsEntry(emp3, t2));
        assertFalse(table.containsEntry(emp3, t3));
        assertTrue(table.containsEntry(emp3, t4));
        assertTrue(table.containsEntry(emp3, t5));

        assertEquals(8, table.entrySet().size());

        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp1, t1)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp1, t2)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp1, t3)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp1, t4)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp1, t5)));

        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp2, t1)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp2, t2)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp2, t3)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp2, t4)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp2, t5)));

        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp3, t1)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp3, t2)));
        assertFalse(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp3, t3)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp3, t4)));
        assertTrue(table.entrySet().contains(new AbstractMap.SimpleEntry<Employee, Task>(emp3, t5)));

        assertTrue(table.keySet().contains(emp1));
        assertTrue(table.keySet().contains(emp2));
        assertTrue(table.keySet().contains(emp3));
        assertFalse(table.keySet().contains(emp4));

        assertTrue(table.valueSet().contains(t1));
        assertTrue(table.valueSet().contains(t2));
        assertTrue(table.valueSet().contains(t3));
        assertTrue(table.valueSet().contains(t4));
        assertTrue(table.valueSet().contains(t5));

        assertTrue(table.valueSet(emp1).contains(t1));
        assertFalse(table.valueSet(emp1).contains(t2));
        assertTrue(table.valueSet(emp1).contains(t3));
        assertFalse(table.valueSet(emp1).contains(t4));
        assertTrue(table.valueSet(emp1).contains(t5));

        assertFalse(table.valueSet(emp2).contains(t1));
        assertTrue(table.valueSet(emp2).contains(t2));
        assertFalse(table.valueSet(emp2).contains(t3));
        assertTrue(table.valueSet(emp2).contains(t4));
        assertFalse(table.valueSet(emp2).contains(t5));

        assertTrue(table.valueSet(emp3).contains(t1));
        assertFalse(table.valueSet(emp3).contains(t2));
        assertFalse(table.valueSet(emp3).contains(t3));
        assertTrue(table.valueSet(emp3).contains(t4));
        assertTrue(table.valueSet(emp3).contains(t5));

        assertTrue(table.keySet(t1).contains(emp1));
        assertFalse(table.keySet(t1).contains(emp2));
        assertTrue(table.keySet(t1).contains(emp3));
        assertFalse(table.keySet(t1).contains(emp4));

        assertFalse(table.keySet(t2).contains(emp1));
        assertTrue(table.keySet(t2).contains(emp2));
        assertFalse(table.keySet(t2).contains(emp3));
        assertFalse(table.keySet(t2).contains(emp4));

        assertTrue(table.keySet(t3).contains(emp1));
        assertFalse(table.keySet(t3).contains(emp2));
        assertFalse(table.keySet(t3).contains(emp3));
        assertFalse(table.keySet(t3).contains(emp4));

        assertFalse(table.keySet(t4).contains(emp1));
        assertTrue(table.keySet(t4).contains(emp2));
        assertTrue(table.keySet(t4).contains(emp3));
        assertFalse(table.keySet(t4).contains(emp4));

        assertTrue(table.keySet(t5).contains(emp1));
        assertFalse(table.keySet(t5).contains(emp2));
        assertTrue(table.keySet(t5).contains(emp3));
        assertFalse(table.keySet(t5).contains(emp4));

    }

    @Test
    public void listTaskByEmployees() {

        Product product = addProduct(managers, "product#1");
        Employee emp1 = addEmployee(managers, "employee#1");
        Position pos1 = addPosition(managers, null, "position#1", false);
        ProductionEvent prod = addProductionEvent(managers, product, shifts.monDay);
        Task event1 = addTask(managers, prod, pos1, shifts.monDay.getStartDate(), shifts.monDay.getEndDate());
        setTaskEmployee(managers, event1, emp1);
        Task event2 = addTask(managers, prod, pos1, shifts.monDay.getStartDate(), shifts.monDay.getEndDate());
        setTaskEmployee(managers, event2, emp1);

        List<Task> events;
        try {
            events = managers.getTaskManager().listByEmployee(shifts.monDay.getStartDate(), shifts.monDay.getEndDate(), emp1);
        } catch (ManagerException e) {
            fail("Fail to list planif events.", e);
            return;
        }
        assertEquals("Wrong number of calendar event.", 2, events.size());
        assertTrue(events.contains(event1));
        assertTrue(events.contains(event2));

    }

    @Test
    public void listTasks() {

        Product product = addProduct(managers, "product#1");
        Position pos1 = addPosition(managers, null, "position#1", false);
        ProductionEvent prod = addProductionEvent(managers, product, shifts.monDay);
        Task event1 = addTask(managers, prod, pos1, shifts.monDay.getStartDate(), shifts.monDay.getEndDate());
        Task event2 = addTask(managers, prod, pos1, shifts.monDay.getStartDate(), shifts.monDay.getEndDate());

        List<Task> events;
        try {
            events = managers.getTaskManager().list(shifts.monDay.getStartDate(), shifts.monDay.getEndDate());
        } catch (ManagerException e) {
            fail("Fail to list planif events.", e);
            return;
        }
        assertEquals("Wrong number of calendar event.", 2, events.size());
        assertTrue(events.contains(event1));
        assertTrue(events.contains(event2));

    }

    /**
     * Sets the first day of week reference.
     */
    @Before
    public void setsFirstDayOfWeek() {
        setFirstDayOfWeek(managers, Calendar.SUNDAY);
    }
}
