/**
 * 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.*;
import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.List;

import org.junit.Assert;
import org.junit.Test;

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

/**
 * This class intend to test the function of {@link NonAvailabilityManager} .
 * 
 * @author ikus060
 * 
 */

public class ShiftManagerTest extends ManagerTestCase {

    @Test
    public void Copy_WithMultipleShiftEvent_WillCopyTheEventsAndSendManagerEvent() throws ManagerException {

        // Create the objects
        Team team = addTeam(managers, "shifts1");
        Shift event1 = addShift(managers, team, dateTime("2012-11-05 Mon 8:00"), dateTime("2012-11-05 Mon 10:00"));
        Shift event2 = addShift(managers, team, dateTime("2012-11-06 Tue 8:00"), dateTime("2012-11-06 Tue 10:00"));

        // Copy them
        addManagerObserver(ManagerEvent.ADD, AbstractCalendarEvent.class);
        managers.getShiftManager().copy(Arrays.asList(event1, event2), time("Wed 8:00"), true);

        // One event for two objects.
        assertEquals("Wrong number of managerevents.", 1, getManagerEvents().size());
        assertManagerEvent(1, getManagerEvents(), ManagerEvent.ADD, null);

        // Query them
        List<? extends AbstractCalendarEvent> events;
        events = managers.getShiftManager().listByTeam(team, time("Mon 0:00"), time("Thu 10:00"));
        assertEquals("Wrong number of calendar events.", 2, events.size());

    }

    @Test
    public void Add_StartGreaterThen_ThrowException() {
        Team shift = addTeam(managers, "shift1");
        Shift event = new Shift();
        event.setTeam(shift);
        event.setStartDate(time("Mon 10:00"));
        event.setEndDate(time("Mon 8:00"));

        // Check date time range
        try {
            managers.getShiftManager().add(Arrays.asList(event));
            // Assert.fail("Adding a calendar with start > end shoud not work.");
        } catch (ManagerException e) {
            // Working
        }
    }

    @Test
    public void Update_WithStartGreaterThenEnd_ThrowException() {

        Team shift = addTeam(managers, "shift1");
        Shift event = addShift(managers, shift, time("Mon 8:00"), time("Mon 10:00"));
        event.setStartDate(time("Mon 10:00"));
        event.setEndDate(time("Mon 8:00"));

        // Check date time range
        try {
            managers.getShiftManager().update(Arrays.asList(event));
            Assert.fail("Adding a calendar with start > end shoud not work.");
        } catch (ManagerException e) {
            // Working
        }
    }

    @Test
    public void ListByShift_ReturnShiftEvents() {
        Team shift = addTeam(managers, "shift1");
        AbstractCalendarEvent event1 = addShift(managers, shift, time("Mon 8:00"), time("Mon 10:00"));
        AbstractCalendarEvent event2 = addShift(managers, shift, time("Tue 8:00"), time("Tue 10:00"));

        List<? extends AbstractCalendarEvent> events;
        try {
            events = managers.getShiftManager().listByTeam(shift, 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));
    }

    @Test
    public void List_WithStartEnd_WillReturnShiftEvents() {

        Team shift1 = addTeam(managers, "shift1");
        AbstractCalendarEvent event1 = addShift(managers, shift1, time("Mon 8:00"), time("Mon 10:00"));
        Team shift2 = addTeam(managers, "shift2");
        AbstractCalendarEvent event2 = addShift(managers, shift2, time("Tue 8:00"), time("Tue 10:00"));

        List<? extends AbstractCalendarEvent> events;
        try {
            events = managers.getShiftManager().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));

    }

    @Test
    public void remove_WithProductionEventAndTasks_removeAllObject() throws ManagerException {
        Team team = addTeam(managers, "shift");
        Shift monDay = addShift(managers, team, time("mon 6:00"), time("mon 16:00"));
        assertEquals(1, managers.getShiftManager().list().size());

        Product product = addProduct(managers, "product");
        Position position = addPosition(managers, null, "position", false);
        ProductionEvent e1 = addProductionEvent(managers, product, monDay);
        assertEquals(1, managers.getProductionEventManager().list().size());

        Task t1 = addTask(managers, e1, position, null, null);
        Task t2 = addTask(managers, e1, position, null, null);
        assertEquals(2, managers.getTaskManager().list().size());

        managers.getShiftManager().remove(Arrays.asList(monDay));

        assertEquals(0, managers.getShiftManager().list().size());
        assertEquals(0, managers.getProductionEventManager().list().size());
        assertEquals(0, managers.getTaskManager().list().size());
    }

}
