/**
 * 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.Arrays;
import java.util.List;

import org.junit.Test;

import com.patrikdufresne.managers.ManagerEvent;
import com.patrikdufresne.managers.ManagerException;

/**
 * This class intend to test the function provided by {@link TeamManager}.
 * 
 * @author ikus060
 * 
 */
public class NonAvailabilityEventManagerTest extends ManagerTestCase {

    @Test
    public void Add_OneNonAvailabilityEvent_WillSendManagerEvent() throws ManagerException {

        addManagerObserver(ManagerEvent.ADD, NonAvailability.class);

        Employee e = addEmployee(managers, null);
        // Add a calendar event
        NonAvailability event = new NonAvailability();
        event.setEmployee(e);

        event.setStartDate(TimeUtils.time("Mon 1:00"));

        event.setEndDate(TimeUtils.time("Mon 2:00"));

        managers.getNonAvailabilityManager().add(Arrays.asList(event));
        assertEquals("Wrong number of managers events.", 1, getManagerEvents().size());

    }

    @Test
    public void List_All_ReturnNonAvailabilities() {

        Employee emp = addEmployee(managers, "employee#1");
        NonAvailability event1 = addNonAvailability(managers, emp, time("Mon 8:00"), time("Mon 10:00"));
        NonAvailability event2 = addNonAvailability(managers, emp, time("Tue 8:00"), time("Tue 10:00"));

        List<NonAvailability> events;
        try {
            events = managers.getNonAvailabilityManager().list();
        } catch (ManagerException e) {
            fail("Fail to list calendar events.", e);
            return;
        }
        assertEquals("Wrong number of calendar event.", 2, events.size());
        assertTrue(events.contains(event1));
        assertTrue(events.contains(event2));

    }

    @Test
    public void List_WithMultipleNonAvailabilities_ReturnAllNonAvailabilities() {

        Employee emp = addEmployee(managers, "employee#1");
        NonAvailability event1 = addNonAvailability(managers, emp, time("Mon 8:00"), time("Mon 10:00"));
        NonAvailability event2 = addNonAvailability(managers, emp, time("Tue 8:00"), time("Tue 10:00"));

        List<NonAvailability> events;
        try {
            events = managers.getNonAvailabilityManager().list(time("Mon 8:00"), time("Tue 10:00"));
        } catch (ManagerException e) {
            fail("Fail to list calendar events.", e);
            return;
        }
        assertEquals("Wrong number of calendar event.", 2, events.size());
        assertTrue(events.contains(event1));
        assertTrue(events.contains(event2));

    }

    /**
     * Check is the list does not contains archived employee.
     * 
     * @throws ManagerException
     */
    @Test
    public void List_WithArchivedEmployee() throws ManagerException {

        Employee emp1 = addEmployee(managers, "employee#1");
        NonAvailability event1 = addNonAvailability(managers, emp1, time("Mon 8:00"), time("Mon 10:00"));
        Employee emp2 = addEmployee(managers, "employee#1");
        NonAvailability event2 = addNonAvailability(managers, emp2, time("Tue 8:00"), time("Tue 10:00"));
        managers.archiveAll(Arrays.asList(emp2));

        List<NonAvailability> events = managers.getNonAvailabilityManager().list(time("Mon 8:00"), time("Tue 10:00"));
        assertEquals(1, events.size());
        assertTrue(events.contains(event1));
        assertFalse(events.contains(event2));

    }

    @Test
    public void ListByEmployees_WithMultipleNonAvailabilities_ReturnSomeNonAvailabilities() {

        Employee emp1 = addEmployee(managers, "employee#1");
        NonAvailability event1 = addNonAvailability(managers, emp1, time("Mon 8:00"), time("Mon 10:00"));
        Employee emp2 = addEmployee(managers, "employee#2");
        NonAvailability event2 = addNonAvailability(managers, emp2, time("Mon 8:00"), time("Mon 10:00"));
        Employee emp3 = addEmployee(managers, "employee#2");
        NonAvailability event3 = addNonAvailability(managers, emp3, time("Mon 8:00"), time("Mon 10:00"));

        List<NonAvailability> nonAvailabilities;
        try {
            nonAvailabilities = managers.getNonAvailabilityManager().listByEmployees(Arrays.asList(emp1, emp2), time("Mon 8:00"), time("Tue 10:00"));
        } catch (ManagerException e) {
            fail("Can't list nonAvailabilities", e);
            return;
        }

        assertEquals("Wrong number of non-availability entry.", 2, nonAvailabilities.size());

    }

}
