/**
******************************************************************************
* Copyright © 2017-2018 PTA GmbH.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* 
*     http://www.eclipse.org/legal/epl-v10.html
* 
******************************************************************************
*/
package org.eclipse.openk.elogbook.controller;

//TODO create Mock for ControllerImplementations (must not use BackendController)

import junit.framework.TestCase;
import org.apache.http.HttpStatus;
import org.eclipse.openk.elogbook.common.util.ResourceLoaderBase;
import org.eclipse.openk.elogbook.controller.ControllerImplementations.GetAllResponsibilities;
import org.eclipse.openk.elogbook.controller.ControllerImplementations.GetCurrentResponsibilities;
import org.eclipse.openk.elogbook.controller.ControllerImplementations.GetIsObserver;
import org.eclipse.openk.elogbook.controller.ControllerImplementations.GetPlannedResponsibilities;
import org.eclipse.openk.elogbook.exceptions.BtbBadRequest;
import org.eclipse.openk.elogbook.exceptions.BtbException;
import org.eclipse.openk.elogbook.persistence.model.RefBranch;
import org.eclipse.openk.elogbook.persistence.model.RefGridTerritory;
import org.eclipse.openk.elogbook.persistence.model.RefNotificationStatus;
import org.eclipse.openk.elogbook.viewmodel.HistoricalShiftChanges;
import org.eclipse.openk.elogbook.viewmodel.Notification;
import org.eclipse.openk.elogbook.viewmodel.TerritoryResponsibility;
import org.eclipse.openk.elogbook.viewmodel.VersionInfo;
import org.junit.Before;
import org.junit.Test;
import org.powermock.api.easymock.PowerMock;

import javax.ws.rs.core.Response;
import java.io.IOException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertNotNull;
import static org.easymock.EasyMock.anyInt;
import static org.easymock.EasyMock.anyObject;
import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expect;
import static org.eclipse.openk.elogbook.controller.BackendControllerResponsibility.POST_RESPONSIBILITY_MODE.PLAN;


public class ControllerImplementationsTest extends ResourceLoaderBase {
    private BackendControllerResponsibility beMockResponsibility;
    private BackendControllerNotification beMockNotification;
    private BackendControllerNotificationFile beMockNotificationFile;
    private BackendControllerUser beMockUser;
    private BackendControllerVersionInfo beMockVersionInfo;
    private BackendControllerRefInfo beMockRefInfo;
    private BackendControllerUser beMockBackendControllerUser;;
    
    @Before
    public void prepareTests() {
        beMockResponsibility = PowerMock.createNiceMock(BackendControllerResponsibility.class);
        beMockNotification = PowerMock.createNiceMock(BackendControllerNotification.class);
        beMockNotificationFile = PowerMock.createNiceMock(BackendControllerNotificationFile.class);
        beMockUser = PowerMock.createNiceMock(BackendControllerUser.class);
        beMockVersionInfo = PowerMock.createNiceMock(BackendControllerVersionInfo.class);
        beMockRefInfo = PowerMock.createNiceMock(BackendControllerRefInfo.class);
        beMockBackendControllerUser = PowerMock.createMock(BackendControllerUser.class);
    }

    @Test
    public void testGetCurrentReponsibilities() throws BtbException {
        List<TerritoryResponsibility> emptyList = new LinkedList<>();

        GetCurrentResponsibilities controllerImpl = new GetCurrentResponsibilities(beMockResponsibility);
        controllerImpl.setModUser( "modUserTest" );
        expect(beMockResponsibility.getCurrentResponsibilities("modUserTest" )).andReturn(emptyList);
        PowerMock.replay(beMockResponsibility);

        TestCase.assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetPlannedReponsibilities() throws BtbException {
        List<TerritoryResponsibility> emptyList = new LinkedList<>();

        GetPlannedResponsibilities controllerImpl = new GetPlannedResponsibilities(beMockResponsibility);
        controllerImpl.setModUser( "modUserTest" );
        expect(beMockResponsibility.getPlannedResponsibilities("modUserTest" )).andReturn(emptyList);
        PowerMock.replay(beMockResponsibility);

        TestCase.assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetAllResponsibilities() throws BtbException {
        List<TerritoryResponsibility> allResponsibilitiesList = new LinkedList<>();

        GetAllResponsibilities controllerImpl = new GetAllResponsibilities(beMockResponsibility);
        expect(beMockResponsibility.getAllResponsibilities()).andReturn(allResponsibilitiesList);
        PowerMock.replay(beMockResponsibility);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

	@Test
	public void testGetHistoricalResponsibilitiesByTransactionId() throws BtbException {
		String id = "1";
		List<TerritoryResponsibility> territoryResponsibilities = new LinkedList<>();
		ControllerImplementations.GetHistoricalResponsibilitiesByTransactionId controllerImpl = new ControllerImplementations.GetHistoricalResponsibilitiesByTransactionId(
				id, beMockResponsibility);

		expect(beMockResponsibility.getHistoricalResponsibilitiesByTransactionId(anyObject())).andReturn(territoryResponsibilities);
		PowerMock.replay(beMockResponsibility);

		assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
	}
    
    @Test
    public void testSearchResults() throws BtbException {
        String gsf = "";
        List<Notification> notifications = new ArrayList<>();
        ControllerImplementations.GetSearchResults controllerImpl = new ControllerImplementations.GetSearchResults(gsf, beMockNotification);

        expect(beMockNotification.getSearchResults(anyObject())).andReturn(notifications);
        PowerMock.replay(beMockNotification);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetNotifications() throws BtbException {
        List<Notification> emptyList = new LinkedList<>();

        ControllerImplementations.GetNotifications controllerImpl = new ControllerImplementations.GetNotifications("OPEN", null, beMockNotification);
        controllerImpl.setModUser("EgalUser");
        controllerImpl.setUserId(1);
        expect(beMockNotification.getNotifications(Notification.ListType.OPEN, null)).andReturn(emptyList);
        PowerMock.replay(beMockNotification);
        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
        assertEquals(controllerImpl.getModUser(), "EgalUser");
        assertEquals(controllerImpl.getUserId(), 1);
    }

    @Test
    public void testGetCurrentReminders() throws BtbException {
        List<Notification> notificationsWithReminderList = new LinkedList<>();
        String emptyFilter = "";

        ControllerImplementations.GetCurrentReminders controllerImpl = new ControllerImplementations.GetCurrentReminders(emptyFilter, beMockNotification);
        controllerImpl.setModUser("EgalUser");
        controllerImpl.setUserId(1);
        expect(beMockNotification.getNotificationsWithReminder(null)).andReturn(notificationsWithReminderList);
        PowerMock.replay(beMockNotification);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
        assertEquals(controllerImpl.getModUser(), "EgalUser");
        assertEquals(controllerImpl.getUserId(), 1);
    }

	@Test
	public void testGetHistoricalShiftChangesList() throws BtbException {
		HistoricalShiftChanges historicalShiftChanges = new HistoricalShiftChanges();
		String emptyFilter = "";

		ControllerImplementations.GetHistoricalShiftChangeList controllerImpl = new ControllerImplementations.GetHistoricalShiftChangeList(
				emptyFilter, beMockResponsibility);
		controllerImpl.setModUser("EgalUser");
		controllerImpl.setUserId(1);
		expect(beMockResponsibility.getHistoricalShiftChanges(null)).andReturn(historicalShiftChanges);
		PowerMock.replay(beMockResponsibility);

		assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
		assertEquals(controllerImpl.getModUser(), "EgalUser");
		assertEquals(controllerImpl.getUserId(), 1);
	}

    @Test
    public void testGetIsObserver() throws BtbException {
        boolean isObserver = false;

        GetIsObserver controllerImpl = new GetIsObserver(beMockResponsibility);
        controllerImpl.setModUser("modUserTest");
        expect(beMockResponsibility.getIsObserver("modUserTest")).andReturn(isObserver);
        PowerMock.replay(beMockResponsibility);
        Response resp = controllerImpl.invoke();
        assertEquals(resp.getStatus(), HttpStatus.SC_OK);
        assertNotNull(resp.getEntity());
        assertEquals(controllerImpl.getModUser(), "modUserTest");
    }

    //FIXME resolve test
    /*@Test
    public void testGetUsers() throws BtbException {
        List<UserAuthentication> userAuthenticationList = new ArrayList<>();

        ControllerImplementations.GetUsers controllerImpl = new ControllerImplementations.GetUsers(beMockUser);
        controllerImpl.setModUser("EgalUser");
        expect(beMockUser.getUsers()).andReturn(userAuthenticationList);
        PowerMock.replay(beMockUser);

        assertEquals(controllerImpl.invoke().getStatus(), Globals.HTTPSTATUS_OK);
        assertEquals(controllerImpl.getModUser(), "EgalUser");
    }*/


    @Test
    public void testPostResponsibilities_NewerRespsAreNull() throws BtbException {
        List<TerritoryResponsibility> territoryResponsibilityList = new ArrayList<>();

        ControllerImplementations.PostResponsibilities controllerImpl = new ControllerImplementations.PostResponsibilities("", true, beMockResponsibility);
        controllerImpl.setModUser("EgalUser");
        expect(beMockResponsibility.postResponsibilities(territoryResponsibilityList, "modUser", PLAN)).andReturn(null);
        PowerMock.replay(beMockResponsibility);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
        assertEquals(controllerImpl.getModUser(), "EgalUser");

    }

    @Test
    public void testPostResponsibilities_NewerRespsNotNull() throws BtbException {
        List<TerritoryResponsibility> territoryResponsibilityList = new ArrayList<>();

        ControllerImplementations.PostResponsibilities controllerImpl = new ControllerImplementations.PostResponsibilities("", true, beMockResponsibility);
        controllerImpl.setModUser("EgalUser");
        expect(beMockResponsibility.postResponsibilities(anyObject(), anyString(), eq(PLAN))).andReturn(new ArrayList<>());
        PowerMock.replay(beMockResponsibility);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
        assertEquals(controllerImpl.getModUser(), "EgalUser");
    }

    @Test
    public void testPostResponsibilitiesConfirmation_NewerRespsAreNull() throws BtbException {
        List<TerritoryResponsibility> territoryResponsiblityList = new ArrayList<>();

        ControllerImplementations.PostResponsibilitiesConfirmation controllerImpl = new ControllerImplementations.PostResponsibilitiesConfirmation("", beMockResponsibility);
        controllerImpl.setModUser("EgalUser");
        expect(beMockResponsibility.confirmResponsibilities(territoryResponsiblityList, "modUser")).andReturn(null);
        PowerMock.replay(beMockResponsibility);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
        assertEquals(controllerImpl.getModUser(), "EgalUser");
    }

    @Test
    public void testPostResponsibilitiesConfirmation_NewerRespsNotNull() throws BtbException {
        List<TerritoryResponsibility> territoryResponsiblityList = new ArrayList<>();

        ControllerImplementations.PostResponsibilitiesConfirmation controllerImpl = new ControllerImplementations.PostResponsibilitiesConfirmation("", beMockResponsibility);
        controllerImpl.setModUser("EgalUser");
        expect(beMockResponsibility.confirmResponsibilities(anyObject(), anyString())).andReturn(new ArrayList<>());
        PowerMock.replay(beMockResponsibility);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
        assertEquals(controllerImpl.getModUser(), "EgalUser");
    }


    @Test
    public void testGetVersionInfo() throws BtbException {
        VersionInfo vi = new VersionInfo();
        ControllerImplementations.GetVersionInfo controllerImpl = new ControllerImplementations.GetVersionInfo(beMockVersionInfo);

        expect(beMockVersionInfo.getVersionInfo()).andReturn(vi);
        PowerMock.replay(beMockVersionInfo);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetBranches() throws BtbException {
        List<RefBranch> rbList = new LinkedList<>();
        rbList.add(new RefBranch());

        ControllerImplementations.GetBranches controllerImpl = new ControllerImplementations.GetBranches(beMockRefInfo);

        expect(beMockRefInfo.getBranches()).andReturn(rbList);
        PowerMock.replay(beMockRefInfo);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetGridTerritories() throws BtbException {
        List<RefGridTerritory> gridTerritories = new LinkedList<>();
        gridTerritories.add(new RefGridTerritory());

        ControllerImplementations.GetGridTerritories controllerImpl = new ControllerImplementations.GetGridTerritories(beMockRefInfo);

        expect(beMockRefInfo.getGridTerritories()).andReturn(gridTerritories);
        PowerMock.replay(beMockRefInfo);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetNotificationStatuses() throws BtbException {
        List<RefNotificationStatus> nsList = new LinkedList<>();
        nsList.add(new RefNotificationStatus());

        ControllerImplementations.GetNotificationStatuses controllerImpl = new ControllerImplementations.GetNotificationStatuses(beMockRefInfo );

        expect(beMockRefInfo.getNotificationStatuses()).andReturn(nsList);
        PowerMock.replay(beMockRefInfo);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }


    @Test
    public void testCreateNotification() throws BtbException {
        String json = super.loadStringFromResource("testSingleNotification.json");

        ControllerImplementations.CreateNotification controllerImpl = new ControllerImplementations.CreateNotification(json, beMockNotification);

        expect(beMockNotification.createNotification(anyObject(), anyObject())).andReturn(new Notification());
        PowerMock.replay(beMockNotification);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test(expected = BtbBadRequest.class)
    public void testCreateNotification_null() throws BtbException {
        ControllerImplementations.CreateNotification controllerImpl = new ControllerImplementations.CreateNotification(null, beMockNotification);

        expect(beMockNotification.createNotification(anyObject(), anyObject())).andReturn(new Notification());
        PowerMock.replay(beMockNotification);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetNotificationById() throws BtbException {
        String id = "100";
        ControllerImplementations.GetNotificationById controllerImpl = new ControllerImplementations.GetNotificationById(id, beMockNotification);

        expect(beMockNotification.getNotificationById(anyObject())).andReturn(new Notification());
        PowerMock.replay(beMockNotification);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetActiveNotifications() throws BtbException {

        ControllerImplementations.GetActiveNotifications controllerImpl = new ControllerImplementations.GetActiveNotifications(beMockNotification);

        expect(beMockNotification.getActiveNotifications()).andReturn(new ArrayList<>());
        PowerMock.replay(beMockNotification);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetNotificationsByIncidentId() throws BtbException {

        ControllerImplementations.GetNotificationsByIncidentId controllerImpl = new ControllerImplementations.GetNotificationsByIncidentId("3", beMockNotification);

        expect(beMockNotification.getNotificationByIncidentId(anyInt())).andReturn(new ArrayList<>());
        PowerMock.replay(beMockNotification);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetAssignedUserSuggestions() throws BtbException {
        List<String> assignedUserSuggestionsList = new LinkedList<>();

        ControllerImplementations.GetAssignedUserSuggestions controllerImpl = new ControllerImplementations.GetAssignedUserSuggestions(beMockUser);
        expect(beMockUser.getAssignedUserSuggestions()).andReturn(assignedUserSuggestionsList);
         PowerMock.replay(beMockUser);

       assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetImportFiles() throws BtbException, IOException {

        ControllerImplementations.GetImportFiles controllerImpl = new ControllerImplementations.GetImportFiles(beMockNotificationFile);

        expect(beMockNotificationFile.getNotificationsFiles("getImportFiles")).andReturn(new ArrayList<>());
        PowerMock.replay(beMockNotificationFile);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testDeleteImportedFiles() throws BtbException, IOException {

        String fileName = "";
        ControllerImplementations.DeleteImportedFiles controllerImpl = new ControllerImplementations.DeleteImportedFiles(fileName, beMockNotificationFile);

        expect(beMockNotificationFile.deleteImportedFile(fileName)).andReturn(true);
        PowerMock.replay(beMockNotificationFile);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testImportFile() throws BtbException, IOException {

        ControllerImplementations.ImportFile controllerImpl = new ControllerImplementations.ImportFile(beMockNotificationFile);

        expect(beMockNotificationFile.getNotificationsFiles("importFile")).andReturn(new ArrayList<>());
        PowerMock.replay(beMockNotificationFile);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }

    @Test
    public void testGetUsers() throws BtbException {
        String token = "";

        ControllerImplementations.GetUsers controllerImpl = new ControllerImplementations.GetUsers(beMockBackendControllerUser, token);

        expect(beMockBackendControllerUser.getUsers(token)).andReturn(new ArrayList<>());
        PowerMock.replay(beMockBackendControllerUser);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
    }


    @Test
    public void testPostUserSettings() throws BtbException {
        String userSettingText = "{}";

        ControllerImplementations.PostUserSettings controllerImpl
                = new ControllerImplementations.PostUserSettings(userSettingText, beMockBackendControllerUser);
        controllerImpl.setModUser("EgalUser");
        expect(beMockBackendControllerUser.storeUserSettings( anyString(), anyString())).andReturn(true);
        PowerMock.replay(beMockBackendControllerUser);

        assertEquals(controllerImpl.invoke().getStatus(), HttpStatus.SC_OK);
        assertEquals(controllerImpl.getModUser(), "EgalUser");
    }

}
