package be.iminds.jfed.gts_highlevel.controller;

import be.iminds.ilabt.jfed.lowlevel.GeniUser;
import be.iminds.ilabt.jfed.lowlevel.GeniUserProvider;
import be.iminds.ilabt.jfed.lowlevel.api.RestApi;
import be.iminds.ilabt.jfed.util.GeniUrn;
import be.iminds.ilabt.jfed.util.JFedPasswordManager;
import be.iminds.ilabt.jfed.util.JavaFXLogger;
import be.iminds.jfed.gts_highlevel.*;
import be.iminds.jfed.gts_highlevel.model.*;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.util.Collections;
import java.util.List;

import static org.mockito.Matchers.*;
import static org.mockito.Mockito.when;
import static org.testng.Assert.*;

/**
 * User: twalcari
 * Date: 9/22/2015
 * Time: 17:34
 */
public class GtsXmlReservationManagerTest {
    public static final String LOGGED_IN_USER_URN_STRING = "urn:publicid:IDN+wall2.ilabt.iminds.be+user+TEST";
    public static final GeniUrn LOGGED_IN_USER_URN = GeniUrn.parse(LOGGED_IN_USER_URN_STRING);

    @Mock
    private GeniUserProvider geniUserProvider;

    @Mock
    private GtsConnectionProvider gtsConnectionProvider;
    @Mock
    private GtsServiceFactory gtsServiceFactory;
    @Mock
    private GtsService gtsService;
    @Mock
    private JavaFXLogger logger;

    @Mock
    private JFedPasswordManager passwordManager;

    private GtsModel model;
    private GtsCredentials fakeCredentials = new GtsCredentials("fake");


    private GtsReservationManager gtsReservationManager;

    @BeforeMethod
    public void beforeMethod() throws Exception {
        MockitoAnnotations.initMocks(this);

        GeniUser loggedInUser = Mockito.mock(GeniUser.class);
        when(loggedInUser.getUserUrn()).thenReturn(LOGGED_IN_USER_URN);
        when(loggedInUser.getUserUrnString()).thenReturn(LOGGED_IN_USER_URN_STRING);

        when(geniUserProvider.getLoggedInGeniUser()).thenReturn(loggedInUser);
        when(passwordManager.getLogins(any())).thenReturn(Collections.singletonList(new JFedPasswordManager.LoginInfo("gts", "gtsuser", "gtspass")));

        when(gtsServiceFactory.createGtsService(any())).thenReturn(gtsService);

        this.model = new GtsModel(passwordManager, null ,geniUserProvider);
        this.gtsReservationManager =
                new GtsReservationManager(fakeCredentials, logger, gtsServiceFactory, gtsConnectionProvider, model);

    }


    @Test
    public void testListUsers() throws Exception {
        when(gtsService.queryUsers(any(), anyString()))
                .thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(), "<?xml version=\"1.0\" encoding=\"UTF-8\"?><users><user><email>systemtestuser@system-test.net</email><login>systemtestuser</login><name>SYSTEMTESTUSER</name><password>systemtestuser</password><project><id>systemtest</id><userLogins>systemtestuser</userLogins><vpnIp>195.113.161.167</vpnIp><vpnPassword>vpnpasssystemtestuser</vpnPassword><vpnUser>vpnsystemtestuser</vpnUser></project><role>user</role></user><user><email>systemtestuser@system-test.net</email><login>systemtestuser</login><name>SYSTEMTESTUSER</name><password>systemtestuser</password><project><id>systemtest</id><userLogins>systemtestuser</userLogins><vpnIp>195.113.161.167</vpnIp><vpnPassword>vpnpasssystemtestuser</vpnPassword><vpnUser>vpnsystemtestuser</vpnUser></project><role>user</role></user><user><email>systemtestuser@system-test.net</email><login>systemtestuser</login><name>SYSTEMTESTUSER</name><password>systemtestuser</password><project><id>systemtest</id><userLogins>systemtestuser</userLogins><vpnIp>195.113.161.167</vpnIp><vpnPassword>vpnpasssystemtestuser</vpnPassword><vpnUser>vpnsystemtestuser</vpnUser></project><role>user</role></user><user><email>systemtestuser@system-test.net</email><login>systemtestuser</login><name>SYSTEMTESTUSER</name><password>systemtestuser</password><project><id>systemtest</id><userLogins>systemtestuser</userLogins><vpnIp>195.113.161.167</vpnIp><vpnPassword>vpnpasssystemtestuser</vpnPassword><vpnUser>vpnsystemtestuser</vpnUser></project><role>user</role></user><user><email>systemtestuser@system-test.net</email><login>systemtestuser</login><name>SYSTEMTESTUSER</name><password>systemtestuser</password><project><id>systemtest</id><userLogins>systemtestuser</userLogins><vpnIp>195.113.161.167</vpnIp><vpnPassword>vpnpasssystemtestuser</vpnPassword><vpnUser>vpnsystemtestuser</vpnUser></project><role>user</role></user><user><email>systemtestuser@system-test.net</email><login>systemtestuser</login><name>SYSTEMTESTUSER</name><password>systemtestuser</password><project><id>systemtest</id><userLogins>systemtestuser</userLogins><vpnIp>195.113.161.167</vpnIp><vpnPassword>vpnpasssystemtestuser</vpnPassword><vpnUser>vpnsystemtestuser</vpnUser></project><role>user</role></user><user><email>garreth.malone@heanet.ie</email><login>gmalone</login><name>Garreth Malone</name><password>Fei7oChu</password><project><id>HEAnet_Test</id><userLogins>gmalone</userLogins><vpnIp>195.113.161.167</vpnIp><vpnPassword>sa2</vpnPassword><vpnUser>sa</vpnUser></project><role>user</role></user><user><email>a@b.c</email><login>oscar</login><name>a</name><password>a</password><project><id>jfed</id><userLogins>jfed</userLogins><userLogins>oscar</userLogins><vpnPassword>jfed</vpnPassword><vpnUser>jfed</vpnUser></project><role>user</role></user><user><email>jfed@localhost.local</email><login>jfed</login><name>jfed</name><password>jfed</password><project><id>jfed</id><userLogins>jfed</userLogins><userLogins>oscar</userLogins><vpnPassword>jfed</vpnPassword><vpnUser>jfed</vpnUser></project><role>admin</role></user><user><email>systemtestuser@system-test.net</email><login>systemtestuser</login><name>SYSTEMTESTUSER</name><password>systemtestuser</password><project><id>systemtest</id><userLogins>systemtestuser</userLogins><vpnIp>195.113.161.167</vpnIp><vpnPassword>vpnpasssystemtestuser</vpnPassword><vpnUser>vpnsystemtestuser</vpnUser></project><role>user</role></user><user><email>systemtestuser@system-test.net</email><login>systemtestuser</login><name>SYSTEMTESTUSER</name><password>systemtestuser</password><project><id>SYSTEM_TEST</id><userLogins>systemtestuser</userLogins><vpnPassword>vpnpasssystemtestuser</vpnPassword><vpnUser>vpnsystemtestuser</vpnUser></project><role>user</role></user><user><email>systemtestuser@system-test.net</email><login>systemtestuser</login><name>SYSTEMTESTUSER</name><password>systemtestuser</password><project><id>SYSTEM_TEST</id><userLogins>systemtestuser</userLogins><vpnPassword>vpnpasssystemtestuser</vpnPassword><vpnUser>vpnsystemtestuser</vpnUser></project><role>user</role></user></users>"));


        List<GtsXmlUser> users = gtsReservationManager.listUsers();

        assertEquals(12, users.size());

        GtsXmlUser firstUser = users.get(0);

        assertEquals(firstUser.getEmail(), "systemtestuser@system-test.net");
        assertEquals(firstUser.getLogin(), "systemtestuser");
    }

    @Test
    public void testListTypes() throws Exception {
        GtsXmlProject project = new GtsXmlProject();
        final String projectId = "JFED";
        project.setId(projectId);

        when(gtsService.queryTypes(any(), anyString(), eq(projectId))).thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(),
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?><types><type><typeName>JFEDTEST</typeName></type></types>"));

        List<GtsXmlType> types = gtsReservationManager.listTypes(project);

        assertEquals(1, types.size());

        GtsXmlType firstType = types.get(0);

        assertEquals(firstType.getName(), "JFEDTEST");

    }

    @Test
    public void testListReservations() throws Exception {
        GtsXmlProject project = new GtsXmlProject();
        final String projectId = "JFED";
        project.setId(projectId);

        when(gtsService.queryReservations(any(), anyString(), eq(projectId))).thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(),
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?><reservations><reservation><id>59</id><endTime>17548354799000</endTime><projectName>jfed</projectName><resourceProviderId>Host-1442504374692</resourceProviderId><status>ACTIVE</status><startTime>1442504340000</startTime></reservation><reservation><id>58</id><endTime>17548354799000</endTime><projectName>jfed</projectName><resourceProviderId>Host-1442504304395</resourceProviderId><status>ACTIVE</status><startTime>1442504280000</startTime></reservation><reservation><children><id>59</id><endTime>17548354799000</endTime><projectName>jfed</projectName><resourceProviderId>Host-1442504374692</resourceProviderId><status>ACTIVE</status><startTime>1442504340000</startTime></children><id>18</id><endTime>17548354799000</endTime><projectName>jfed</projectName><resourceProviderId>67</resourceProviderId><status>ACTIVE</status><startTime>1442504340000</startTime></reservation><reservation><children><id>58</id><endTime>17548354799000</endTime><projectName>jfed</projectName><resourceProviderId>Host-1442504304395</resourceProviderId><status>ACTIVE</status><startTime>1442504280000</startTime></children><id>17</id><endTime>17548354799000</endTime><projectName>jfed</projectName><resourceProviderId>66</resourceProviderId><status>ACTIVE</status><startTime>1442504280000</startTime></reservation></reservations>"));

        List<GtsXmlReservation> reservations = gtsReservationManager.listReservations(project);

        assertEquals(reservations.size(), 4);

        GtsXmlReservation firstReservation = reservations.get(0);

        assertEquals(firstReservation.getId(), new Integer(59));
        assertEquals(firstReservation.getProjectName().toLowerCase(), projectId.toLowerCase());
        assertEquals(firstReservation.getStatus(), GtsXmlReservation.Status.ACTIVE);
        assertEquals(firstReservation.getResourcesProviderId(), "Host-1442504374692");
        assertEquals(firstReservation.getStartTime().toEpochSecond() * 1000, 1442504340000L);


        GtsXmlReservation lastReservation = reservations.get(3);
        assertEquals(lastReservation.getChildren().size(), 1);
        GtsXmlReservation childReservation = lastReservation.getChildren().get(0);
        assertEquals(childReservation.getId(), new Integer(58));
        assertEquals(childReservation.getStatus(), GtsXmlReservation.Status.ACTIVE);

    }

    @Test
    public void testListResources() throws Exception {
        when(gtsService.queryAllResources(any(), anyString())).thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(),
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?><resourceBases><composite><capabilities><entry><key>id</key><value>657217</value></entry><entry><key>ports</key><value>{}</value></entry><entry><key>status</key><value>RESERVING</value></entry><entry><key>providerId</key><value>64</value></entry><entry><key>type</key><value>Testbed</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>657217</id><ports/><providerId>64</providerId><reservations><children><id>56</id><endTime>17548354799000</endTime><resourceProviderId>Host-1442502558326</resourceProviderId><status>RESERVED</status><startTime>1442502540000</startTime></children><id>15</id><endTime>17548354799000</endTime><resourceProviderId>64</resourceProviderId><status>RESERVING</status><startTime>1442502540000</startTime></reservations><status>RESERVING</status><type>Testbed</type><name>ExternalExample</name></composite><composite><capabilities><entry><key>id</key><value>248103</value></entry><entry><key>ports</key><value>{}</value></entry><entry><key>status</key><value>ACTIVE</value></entry><entry><key>providerId</key><value>66</value></entry><entry><key>type</key><value>Testbed</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>248103</id><ports/><providerId>66</providerId><reservations><children><id>58</id><endTime>17548354799000</endTime><resourceProviderId>Host-1442504304395</resourceProviderId><status>ACTIVE</status><startTime>1442504280000</startTime></children><id>17</id><endTime>17548354799000</endTime><resourceProviderId>66</resourceProviderId><status>ACTIVE</status><startTime>1442504280000</startTime></reservations><status>ACTIVE</status><type>Testbed</type><name>JFEDTEST</name></composite><composite><capabilities><entry><key>id</key><value>248432</value></entry><entry><key>ports</key><value>{}</value></entry><entry><key>status</key><value>ACTIVE</value></entry><entry><key>providerId</key><value>67</value></entry><entry><key>type</key><value>Testbed</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>248432</id><ports/><providerId>67</providerId><reservations><children><id>59</id><endTime>17548354799000</endTime><resourceProviderId>Host-1442504374692</resourceProviderId><status>ACTIVE</status><startTime>1442504340000</startTime></children><id>18</id><endTime>17548354799000</endTime><resourceProviderId>67</resourceProviderId><status>ACTIVE</status><startTime>1442504340000</startTime></reservations><status>ACTIVE</status><type>Testbed</type><name>JFEDTEST</name></composite><resourceBase><capabilities><entry><key>id</key><value>h1</value></entry><entry><key>ports</key><value>{eth1=Port [id=eth1, dbId=109, mtu=0, speed=0, mode=DATA, parent=h1STP=STP [dbId=12, , /taas/vms/lab1\\/lab1/compute0/eth15 {id=eth15, fileLocation=/home/taas/testeth15.xml, location=lab1, computeNode=lab1-compute0, computeNodeIp=10.0.0.18, userName=taas, password=0SHost1ngXY}]], eth2=Port [id=eth2, dbId=110, mtu=0, speed=0, mode=DATA, parent=h1STP=STP [dbId=11, , /taas/vms/lab1\\/lab1/compute0/eth14 {id=eth14, fileLocation=/home/taas/testeth14.xml, location=lab1, computeNode=lab1-compute0, computeNodeIp=10.0.0.18, userName=taas, password=0SHost1ngXY}]]}</value></entry><entry><key>cpuCores</key><value>-1</value></entry><entry><key>location</key><value>LAB1</value></entry><entry><key>status</key><value>RESERVED</value></entry><entry><key>portNum</key><value>2</value></entry><entry><key>providerId</key><value>Host-1442502558326</value></entry><entry><key>type</key><value>Host</value></entry><entry><key>memory</key><value>-1</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>h1</id><ports><entry><key>eth1</key><value><id>eth1</id><mode>DATA</mode><parent>Host-1442502558326</parent><properties/><STP><localId>/lab1/compute0/eth15</localId><networkId>/taas/vms/lab1</networkId><remote>false</remote></STP><version>0</version></value></entry><entry><key>eth2</key><value><id>eth2</id><mode>DATA</mode><parent>Host-1442502558326</parent><properties/><STP><localId>/lab1/compute0/eth14</localId><networkId>/taas/vms/lab1</networkId><remote>false</remote></STP><version>0</version></value></entry></ports><providerId>Host-1442502558326</providerId><reservations><id>56</id><endTime>17548354799000</endTime><resourceProviderId>Host-1442502558326</resourceProviderId><status>RESERVED</status><startTime>1442502540000</startTime></reservations><status>RESERVED</status><type>Host</type></resourceBase><resourceBase><capabilities><entry><key>id</key><value>h1</value></entry><entry><key>ports</key><value>{}</value></entry><entry><key>console</key><value>http://195.113.161.164:6080/vnc_auto.html?token=bd15a90d-11ed-4120-b746-92544b76292b</value></entry><entry><key>imageId</key><value>cb75f988-43f1-4141-9948-df286cc59dfb</value></entry><entry><key>cpuCores</key><value>-1</value></entry><entry><key>location</key><value>LAB1</value></entry><entry><key>status</key><value>ACTIVE</value></entry><entry><key>portNum</key><value>0</value></entry><entry><key>providerId</key><value>Host-1442504304395</value></entry><entry><key>type</key><value>Host</value></entry><entry><key>memory</key><value>-1</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>h1</id><ports/><providerId>Host-1442504304395</providerId><reservations><id>58</id><endTime>17548354799000</endTime><resourceProviderId>Host-1442504304395</resourceProviderId><status>ACTIVE</status><startTime>1442504280000</startTime></reservations><status>ACTIVE</status><type>Host</type></resourceBase><resourceBase><capabilities><entry><key>id</key><value>h1</value></entry><entry><key>ports</key><value>{}</value></entry><entry><key>console</key><value>http://195.113.161.164:6080/vnc_auto.html?token=51820872-cedc-403f-bacd-98a7514bba92</value></entry><entry><key>imageId</key><value>cb75f988-43f1-4141-9948-df286cc59dfb</value></entry><entry><key>cpuCores</key><value>-1</value></entry><entry><key>location</key><value>LAB1</value></entry><entry><key>status</key><value>ACTIVE</value></entry><entry><key>portNum</key><value>0</value></entry><entry><key>providerId</key><value>Host-1442504374692</value></entry><entry><key>type</key><value>Host</value></entry><entry><key>memory</key><value>-1</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>h1</id><ports/><providerId>Host-1442504374692</providerId><reservations><id>59</id><endTime>17548354799000</endTime><resourceProviderId>Host-1442504374692</resourceProviderId><status>ACTIVE</status><startTime>1442504340000</startTime></reservations><status>ACTIVE</status><type>Host</type></resourceBase></resourceBases>"));


        List<GtsXmlResource> resources = gtsReservationManager.listResources();

        assertEquals(resources.size(), 6);

        GtsXmlResource firstResource = resources.get(0);
        assertTrue(firstResource instanceof GtsXmlComposite);
        assertEquals(((GtsXmlComposite) firstResource).getName(), "ExternalExample");
        assertEquals(firstResource.getType(), GtsXmlResource.Type.Testbed);
        assertEquals(firstResource.getStatus(), GtsXmlReservation.Status.RESERVING);
        assertNotNull(firstResource.getReservations());
    }

    @Test
    public void testGetResource() throws Exception {
        when(gtsService.queryResource(any(), anyString(), eq("66"))).thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(),
                "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><composite><capabilities><entry><key>id</key><value>248103</value></entry><entry><key>ports</key><value>{}</value></entry><entry><key>status</key><value>ACTIVE</value></entry><entry><key>providerId</key><value>66</value></entry><entry><key>type</key><value>Testbed</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>248103</id><ports/><providerId>66</providerId><reservations><children><id>58</id><endTime>17548354799000</endTime><resourceProviderId>Host-1442504304395</resourceProviderId><status>ACTIVE</status><startTime>1442504280000</startTime></children><id>17</id><endTime>17548354799000</endTime><resourceProviderId>66</resourceProviderId><status>ACTIVE</status><startTime>1442504280000</startTime></reservations><status>ACTIVE</status><type>Testbed</type><name>JFEDTEST</name></composite>"));

        GtsXmlResource resource = gtsReservationManager.getResource(66);

        assertNotNull(resource);
        assertEquals(resource.getProviderId(), "66");
        assertTrue(resource instanceof GtsXmlComposite);
        assertNotNull(resource.getReservations());
        assertEquals(resource.getReservations().getId(), new Integer(17));
        assertEquals(resource.getReservations().getChildren().size(), 1);
        assertEquals(resource.getReservations().getChildren().get(0).getId(), new Integer(58));

    }

    @Test
    public void testGetProject() throws Exception {
        final String projectId = "jfed";
        when(gtsService.queryProject(any(), anyString(), eq(projectId))).thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(),
                "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><project><id>jfed</id><userLogins>jfed</userLogins><vpnIp>195.113.161.168</vpnIp><vpnPassword>jfed</vpnPassword><vpnUser>jfed</vpnUser></project>"
        ));

        GtsXmlProject project = gtsReservationManager.getProject(projectId);

        assertNotNull(project);
        assertEquals(project.getId(), projectId);
        assertEquals(project.getUserLogins(), Collections.singletonList("jfed"));
        assertEquals(project.getVpnUser(), "jfed");
        assertEquals(project.getVpnPassword(), "jfed");
        assertEquals(project.getVpnIp(), "195.113.161.168");
    }

    @Test
    public void testListProjects() throws Exception {
        when(gtsService.queryProjects(any(), anyString())).thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(), "<?xml version=\"1.0\" encoding=\"UTF-8\"?><projects><project><id>SYSTEM_TEST_MATRIX</id><userLogins>systemtestuser</userLogins><vpnPassword>vpnpasssystemtestuser</vpnPassword><vpnUser>vpnsystemtestuser</vpnUser></project><project><id>SYSTEM_TEST</id><userLogins>systemtestuser</userLogins><vpnPassword>vpnpasssystemtestuser</vpnPassword><vpnUser>vpnsystemtestuser</vpnUser></project><project><id>jfed</id><userLogins>jfed</userLogins><vpnIp>195.113.161.168</vpnIp><vpnPassword>jfed</vpnPassword><vpnUser>jfed</vpnUser></project></projects>"));

        List<GtsXmlProject> projects = gtsReservationManager.listProjects();

        assertEquals(projects.size(), 3);

        GtsXmlProject project = projects.get(2);
        assertEquals(project.getId(), "jfed");
        assertEquals(project.getUserLogins(), Collections.singletonList("jfed"));
        assertEquals(project.getVpnUser(), "jfed");
        assertEquals(project.getVpnPassword(), "jfed");
        assertEquals(project.getVpnIp(), "195.113.161.168");


    }

    @Test
    public void testListInfrastructures() throws Exception {
        when(gtsService.queryRCAs(any(), anyString())).thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(),
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?><infrastructures><infrastructure><capabilities/><providerId>OpenFlow</providerId></infrastructure><infrastructure><capabilities><entry><key>description</key><value xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">TaaS Mock Infrastructure</value></entry></capabilities><description>TaaS Mock Infrastructure</description><providerId>Mock Infrastructure</providerId></infrastructure><infrastructure><capabilities><entry><key>description</key><value xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">TaaS External Domain Infrastructure</value></entry></capabilities><description>TaaS External Domain Infrastructure</description><providerId>External Domain Infrastructure</providerId></infrastructure><infrastructure><capabilities/><providerId>Remote Infrastructure</providerId></infrastructure><infrastructure><capabilities/><providerId>OpenStack</providerId></infrastructure></infrastructures>"));


        List<GtsInfrastructure> infrastructures = gtsReservationManager.listInfrastructures();

        assertEquals(infrastructures.size(), 5);

        GtsInfrastructure firstInfrastructure = infrastructures.get(0);
        assertEquals(firstInfrastructure.getProviderId(), "OpenFlow");
        assertEquals(firstInfrastructure.getCapabilities(), Collections.emptyMap());
    }

    @Test
    public void testGetInfrastructure() throws Exception {
        final String id = "Mock Infrastructure";
        when(gtsService.queryRCA(any(), anyString(), eq(id)))
                .thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(), "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><infrastructure><capabilities><entry><key>description</key><value xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xs=\"http://www.w3.org/2001/XMLSchema\" xsi:type=\"xs:string\">TaaS Mock Infrastructure</value></entry></capabilities><description>TaaS Mock Infrastructure</description><providerId>Mock Infrastructure</providerId><resources><capabilities><entry><key>id</key><value>8</value></entry><entry><key>dummyText</key><value>I am dummy no 8</value></entry><entry><key>ports</key><value>{p4=Port [id=p4, dbId=1, mtu=0, speed=0, mode=DATA, parent=8], p3=Port [id=p3, dbId=2, mtu=0, speed=0, mode=DATA, parent=8], p2=Port [id=p2, dbId=3, mtu=0, speed=0, mode=DATA, parent=8], p1=Port [id=p1, dbId=4, mtu=0, speed=0, mode=DATA, parent=8]}</value></entry><entry><key>location</key><value>CPH</value></entry><entry><key>status</key><value>AVAILABLE</value></entry><entry><key>providerId</key><value>node8</value></entry><entry><key>type</key><value>DummyNode</value></entry><entry><key>dummyValue</key><value>0</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>8</id><ports><entry><key>p4</key><value><id>p4</id><mode>DATA</mode><parent>node8</parent><properties/><version>0</version></value></entry><entry><key>p3</key><value><id>p3</id><mode>DATA</mode><parent>node8</parent><properties/><version>0</version></value></entry><entry><key>p2</key><value><id>p2</id><mode>DATA</mode><parent>node8</parent><properties/><version>0</version></value></entry><entry><key>p1</key><value><id>p1</id><mode>DATA</mode><parent>node8</parent><properties/><version>0</version></value></entry></ports><providerId>node8</providerId><status>NULL</status><type>DummyNode</type><version>0</version></resources><resources><capabilities><entry><key>id</key><value>7</value></entry><entry><key>dummyText</key><value>I am dummy no 7</value></entry><entry><key>ports</key><value>{p4=Port [id=p4, dbId=5, mtu=0, speed=0, mode=DATA, parent=7], p3=Port [id=p3, dbId=6, mtu=0, speed=0, mode=DATA, parent=7], p2=Port [id=p2, dbId=7, mtu=0, speed=0, mode=DATA, parent=7], p1=Port [id=p1, dbId=8, mtu=0, speed=0, mode=DATA, parent=7]}</value></entry><entry><key>location</key><value>BRA</value></entry><entry><key>status</key><value>AVAILABLE</value></entry><entry><key>providerId</key><value>node7</value></entry><entry><key>type</key><value>DummyNode</value></entry><entry><key>dummyValue</key><value>0</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>7</id><ports><entry><key>p4</key><value><id>p4</id><mode>DATA</mode><parent>node7</parent><properties/><version>0</version></value></entry><entry><key>p3</key><value><id>p3</id><mode>DATA</mode><parent>node7</parent><properties/><version>0</version></value></entry><entry><key>p2</key><value><id>p2</id><mode>DATA</mode><parent>node7</parent><properties/><version>0</version></value></entry><entry><key>p1</key><value><id>p1</id><mode>DATA</mode><parent>node7</parent><properties/><version>0</version></value></entry></ports><providerId>node7</providerId><status>NULL</status><type>DummyNode</type><version>0</version></resources><resources><capabilities><entry><key>id</key><value>6</value></entry><entry><key>dummyText</key><value>I am dummy no 6</value></entry><entry><key>ports</key><value>{p4=Port [id=p4, dbId=9, mtu=0, speed=0, mode=DATA, parent=6], p3=Port [id=p3, dbId=10, mtu=0, speed=0, mode=DATA, parent=6], p2=Port [id=p2, dbId=11, mtu=0, speed=0, mode=DATA, parent=6], p1=Port [id=p1, dbId=12, mtu=0, speed=0, mode=DATA, parent=6]}</value></entry><entry><key>location</key><value>CPH</value></entry><entry><key>status</key><value>AVAILABLE</value></entry><entry><key>providerId</key><value>node6</value></entry><entry><key>type</key><value>DummyNode</value></entry><entry><key>dummyValue</key><value>0</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>6</id><ports><entry><key>p4</key><value><id>p4</id><mode>DATA</mode><parent>node6</parent><properties/><version>0</version></value></entry><entry><key>p3</key><value><id>p3</id><mode>DATA</mode><parent>node6</parent><properties/><version>0</version></value></entry><entry><key>p2</key><value><id>p2</id><mode>DATA</mode><parent>node6</parent><properties/><version>0</version></value></entry><entry><key>p1</key><value><id>p1</id><mode>DATA</mode><parent>node6</parent><properties/><version>0</version></value></entry></ports><providerId>node6</providerId><status>NULL</status><type>DummyNode</type><version>0</version></resources><resources><capabilities><entry><key>id</key><value>5</value></entry><entry><key>dummyText</key><value>I am dummy no 5</value></entry><entry><key>ports</key><value>{p4=Port [id=p4, dbId=13, mtu=0, speed=0, mode=DATA, parent=5], p3=Port [id=p3, dbId=14, mtu=0, speed=0, mode=DATA, parent=5], p2=Port [id=p2, dbId=15, mtu=0, speed=0, mode=DATA, parent=5], p1=Port [id=p1, dbId=16, mtu=0, speed=0, mode=DATA, parent=5]}</value></entry><entry><key>location</key><value>BRA</value></entry><entry><key>status</key><value>AVAILABLE</value></entry><entry><key>providerId</key><value>node5</value></entry><entry><key>type</key><value>DummyNode</value></entry><entry><key>dummyValue</key><value>0</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>5</id><ports><entry><key>p4</key><value><id>p4</id><mode>DATA</mode><parent>node5</parent><properties/><version>0</version></value></entry><entry><key>p3</key><value><id>p3</id><mode>DATA</mode><parent>node5</parent><properties/><version>0</version></value></entry><entry><key>p2</key><value><id>p2</id><mode>DATA</mode><parent>node5</parent><properties/><version>0</version></value></entry><entry><key>p1</key><value><id>p1</id><mode>DATA</mode><parent>node5</parent><properties/><version>0</version></value></entry></ports><providerId>node5</providerId><status>NULL</status><type>DummyNode</type><version>0</version></resources><resources><capabilities><entry><key>id</key><value>4</value></entry><entry><key>dummyText</key><value>I am dummy no 4</value></entry><entry><key>ports</key><value>{p4=Port [id=p4, dbId=17, mtu=0, speed=0, mode=DATA, parent=4], p3=Port [id=p3, dbId=18, mtu=0, speed=0, mode=DATA, parent=4], p2=Port [id=p2, dbId=19, mtu=0, speed=0, mode=DATA, parent=4], p1=Port [id=p1, dbId=20, mtu=0, speed=0, mode=DATA, parent=4]}</value></entry><entry><key>location</key><value>CPH</value></entry><entry><key>status</key><value>AVAILABLE</value></entry><entry><key>providerId</key><value>node4</value></entry><entry><key>type</key><value>DummyNode</value></entry><entry><key>dummyValue</key><value>0</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>4</id><ports><entry><key>p4</key><value><id>p4</id><mode>DATA</mode><parent>node4</parent><properties/><version>0</version></value></entry><entry><key>p3</key><value><id>p3</id><mode>DATA</mode><parent>node4</parent><properties/><version>0</version></value></entry><entry><key>p2</key><value><id>p2</id><mode>DATA</mode><parent>node4</parent><properties/><version>0</version></value></entry><entry><key>p1</key><value><id>p1</id><mode>DATA</mode><parent>node4</parent><properties/><version>0</version></value></entry></ports><providerId>node4</providerId><status>NULL</status><type>DummyNode</type><version>0</version></resources><resources><capabilities><entry><key>id</key><value>3</value></entry><entry><key>dummyText</key><value>I am dummy no 3</value></entry><entry><key>ports</key><value>{p4=Port [id=p4, dbId=21, mtu=0, speed=0, mode=DATA, parent=3], p3=Port [id=p3, dbId=22, mtu=0, speed=0, mode=DATA, parent=3], p2=Port [id=p2, dbId=23, mtu=0, speed=0, mode=DATA, parent=3], p1=Port [id=p1, dbId=24, mtu=0, speed=0, mode=DATA, parent=3]}</value></entry><entry><key>location</key><value>BRA</value></entry><entry><key>status</key><value>AVAILABLE</value></entry><entry><key>providerId</key><value>node3</value></entry><entry><key>type</key><value>DummyNode</value></entry><entry><key>dummyValue</key><value>0</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>3</id><ports><entry><key>p4</key><value><id>p4</id><mode>DATA</mode><parent>node3</parent><properties/><version>0</version></value></entry><entry><key>p3</key><value><id>p3</id><mode>DATA</mode><parent>node3</parent><properties/><version>0</version></value></entry><entry><key>p2</key><value><id>p2</id><mode>DATA</mode><parent>node3</parent><properties/><version>0</version></value></entry><entry><key>p1</key><value><id>p1</id><mode>DATA</mode><parent>node3</parent><properties/><version>0</version></value></entry></ports><providerId>node3</providerId><status>NULL</status><type>DummyNode</type><version>0</version></resources><resources><capabilities><entry><key>id</key><value>2</value></entry><entry><key>dummyText</key><value>I am dummy no 2</value></entry><entry><key>ports</key><value>{p4=Port [id=p4, dbId=25, mtu=0, speed=0, mode=DATA, parent=2], p3=Port [id=p3, dbId=26, mtu=0, speed=0, mode=DATA, parent=2], p2=Port [id=p2, dbId=27, mtu=0, speed=0, mode=DATA, parent=2], p1=Port [id=p1, dbId=28, mtu=0, speed=0, mode=DATA, parent=2]}</value></entry><entry><key>location</key><value>CPH</value></entry><entry><key>status</key><value>AVAILABLE</value></entry><entry><key>providerId</key><value>node2</value></entry><entry><key>type</key><value>DummyNode</value></entry><entry><key>dummyValue</key><value>0</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>2</id><ports><entry><key>p4</key><value><id>p4</id><mode>DATA</mode><parent>node2</parent><properties/><version>0</version></value></entry><entry><key>p3</key><value><id>p3</id><mode>DATA</mode><parent>node2</parent><properties/><version>0</version></value></entry><entry><key>p2</key><value><id>p2</id><mode>DATA</mode><parent>node2</parent><properties/><version>0</version></value></entry><entry><key>p1</key><value><id>p1</id><mode>DATA</mode><parent>node2</parent><properties/><version>0</version></value></entry></ports><providerId>node2</providerId><status>NULL</status><type>DummyNode</type><version>0</version></resources><resources><capabilities><entry><key>id</key><value>1</value></entry><entry><key>dummyText</key><value>I am dummy no 1</value></entry><entry><key>ports</key><value>{p4=Port [id=p4, dbId=29, mtu=0, speed=0, mode=DATA, parent=1], p3=Port [id=p3, dbId=30, mtu=0, speed=0, mode=DATA, parent=1], p2=Port [id=p2, dbId=31, mtu=0, speed=0, mode=DATA, parent=1], p1=Port [id=p1, dbId=32, mtu=0, speed=0, mode=DATA, parent=1]}</value></entry><entry><key>location</key><value>BRA</value></entry><entry><key>status</key><value>AVAILABLE</value></entry><entry><key>providerId</key><value>node1</value></entry><entry><key>type</key><value>DummyNode</value></entry><entry><key>dummyValue</key><value>0</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>1</id><ports><entry><key>p4</key><value><id>p4</id><mode>DATA</mode><parent>node1</parent><properties/><version>0</version></value></entry><entry><key>p3</key><value><id>p3</id><mode>DATA</mode><parent>node1</parent><properties/><version>0</version></value></entry><entry><key>p2</key><value><id>p2</id><mode>DATA</mode><parent>node1</parent><properties/><version>0</version></value></entry><entry><key>p1</key><value><id>p1</id><mode>DATA</mode><parent>node1</parent><properties/><version>0</version></value></entry></ports><providerId>node1</providerId><status>NULL</status><type>DummyNode</type><version>0</version></resources><resources><capabilities><entry><key>id</key><value>0</value></entry><entry><key>dummyText</key><value>I am dummy no 0</value></entry><entry><key>ports</key><value>{p4=Port [id=p4, dbId=33, mtu=0, speed=0, mode=DATA, parent=0], p3=Port [id=p3, dbId=34, mtu=0, speed=0, mode=DATA, parent=0], p2=Port [id=p2, dbId=35, mtu=0, speed=0, mode=DATA, parent=0], p1=Port [id=p1, dbId=36, mtu=0, speed=0, mode=DATA, parent=0]}</value></entry><entry><key>location</key><value>CPH</value></entry><entry><key>status</key><value>AVAILABLE</value></entry><entry><key>providerId</key><value>node0</value></entry><entry><key>type</key><value>DummyNode</value></entry><entry><key>dummyValue</key><value>0</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>0</id><ports><entry><key>p4</key><value><id>p4</id><mode>DATA</mode><parent>node0</parent><properties/><version>0</version></value></entry><entry><key>p3</key><value><id>p3</id><mode>DATA</mode><parent>node0</parent><properties/><version>0</version></value></entry><entry><key>p2</key><value><id>p2</id><mode>DATA</mode><parent>node0</parent><properties/><version>0</version></value></entry><entry><key>p1</key><value><id>p1</id><mode>DATA</mode><parent>node0</parent><properties/><version>0</version></value></entry></ports><providerId>node0</providerId><status>NULL</status><type>DummyNode</type><version>0</version></resources><resources><capabilities><entry><key>id</key><value>9</value></entry><entry><key>dummyText</key><value>I am dummy no 9</value></entry><entry><key>ports</key><value>{p4=Port [id=p4, dbId=37, mtu=0, speed=0, mode=DATA, parent=9], p3=Port [id=p3, dbId=38, mtu=0, speed=0, mode=DATA, parent=9], p2=Port [id=p2, dbId=39, mtu=0, speed=0, mode=DATA, parent=9], p1=Port [id=p1, dbId=40, mtu=0, speed=0, mode=DATA, parent=9]}</value></entry><entry><key>location</key><value>BRA</value></entry><entry><key>status</key><value>AVAILABLE</value></entry><entry><key>providerId</key><value>node9</value></entry><entry><key>type</key><value>DummyNode</value></entry><entry><key>dummyValue</key><value>0</value></entry></capabilities><failOnActivate>false</failOnActivate><failOnDeactivate>false</failOnDeactivate><id>9</id><ports><entry><key>p4</key><value><id>p4</id><mode>DATA</mode><parent>node9</parent><properties/><version>0</version></value></entry><entry><key>p3</key><value><id>p3</id><mode>DATA</mode><parent>node9</parent><properties/><version>0</version></value></entry><entry><key>p2</key><value><id>p2</id><mode>DATA</mode><parent>node9</parent><properties/><version>0</version></value></entry><entry><key>p1</key><value><id>p1</id><mode>DATA</mode><parent>node9</parent><properties/><version>0</version></value></entry></ports><providerId>node9</providerId><status>NULL</status><type>DummyNode</type><version>0</version></resources></infrastructure>"));

        GtsInfrastructure infrastructure = gtsReservationManager.getInfrastructure(id);

        assertEquals(infrastructure.getProviderId(), id);
        assertEquals(infrastructure.getCapabilities(), Collections.singletonMap("description", "TaaS Mock Infrastructure"));
        assertEquals(infrastructure.getResources().size(), 10);


    }

    @Test
    public void testAddType() throws Exception {
        final String script = "type testscript {\n" +
                "description = \"test desc\"\n" +
                "id = \"jfedtestid\"\n" +
                "host {\n" +
                " \t id = \"host0\"\n" +
                " \t image = \"Ubuntu 14.04\"\n" +
                " \t cpuSpeed = 2.3\n" +
                " \t disk = 20\n" +
                " \t port {id = \"p0\"\n" +
                "\t\txpos=18\n" +
                "\t\typos=0}\n" +
                "\txpos = 200\n" +
                "\typos = 100\n" +
                "}\n" +
                "host {\n" +
                " \t id = \"host1\"\n" +
                " \t image = \"Ubuntu 14.04\"\n" +
                " \t cpuSpeed = 2.3\n" +
                " \t disk = 20\n" +
                " \t port {id = \"p0\"\n" +
                "\t\txpos=18\n" +
                "\t\typos=0}\n" +
                "\txpos = 549\n" +
                "\typos = 97\n" +
                "}\n" +
                "}";

        final String projectName = "jfed";
        final String resultName = "testscript";
        when(gtsService.addType(any(), anyString(), eq(projectName), eq(script))).thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(), resultName));

        GtsXmlProject project = new GtsXmlProject();
        project.setId(projectName);

        String newTypeName = gtsReservationManager.addType(script, project);

        assertEquals(newTypeName, resultName);
    }

    @Test
    public void testRemoveType() throws Exception {

        final String projectName = "jfed";
        final String typeName = "testscript";

        when(gtsService.removeType(any(), anyString(), eq(projectName), eq(typeName))).thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(), typeName));
        GtsXmlProject project = new GtsXmlProject();
        project.setId(projectName);
        GtsXmlType type = new GtsXmlType(typeName);

        gtsReservationManager.removeType(project, type);
    }

    @Test(expectedExceptions = GtsException.class)
    public void testRemoveNonExistingType() throws Exception {

        final String projectName = "jfed";
        final String scriptName = "non-existing-script";
        when(gtsService.removeType(any(), anyString(), eq(projectName), eq(scriptName)))
                .thenReturn(new RestApi.RestReply<>(new Mock404HttpCallDetails(), ""));

        GtsXmlProject project = new GtsXmlProject();
        project.setId(projectName);
        GtsXmlType type = new GtsXmlType(scriptName);

        gtsReservationManager.removeType(project, type);
    }

    @Test
    public void testReserveType() throws Exception {

        final String projectName = "jfed";
        final String typeName = "jfedtest";
        when(gtsService.reserveType(any(), anyString(), eq(typeName), eq(projectName)))
                .thenReturn(new RestApi.RestReply<>(new MockHttpCallDetails(), "67"));

        GtsXmlProject project = new GtsXmlProject();
        project.setId(projectName);
        GtsXmlType type = new GtsXmlType(typeName);

        int result = gtsReservationManager.reserveType(project, type);

        assertEquals(result, 67);
    }

    @Test
    public void testActivateReservation() throws Exception {
        final int reservationId = 67;
        when(gtsService.activateReservation(any(), anyString(), eq(Integer.toString(reservationId))))
                .thenReturn(new RestApi.RestReply<>(new Mock204HttpCallDetails(), ""));

        gtsReservationManager.activateReservation(reservationId);
    }

    @Test(expectedExceptions = GtsException.class, expectedExceptionsMessageRegExp = "A server-side error .*404.*")
    public void testActivateNonExistingReservation() throws Exception {
        final int reservationId = 66;
        when(gtsService.activateReservation(any(), anyString(), eq(Integer.toString(reservationId))))
                .thenReturn(new RestApi.RestReply<>(new Mock404HttpCallDetails(), ""));

        gtsReservationManager.activateReservation(reservationId);
    }

    @Test
    public void testDeactivateReservation() throws Exception {
        final int reservationId = 67;
        when(gtsService.deactivateReservation(any(), anyString(), eq(Integer.toString(reservationId))))
                .thenReturn(new RestApi.RestReply<>(new Mock204HttpCallDetails(), ""));

        gtsReservationManager.deactivateReservation(reservationId);
    }

    @Test(expectedExceptions = GtsException.class, expectedExceptionsMessageRegExp = "A server-side error .*404.*")
    public void testDeactivateNonExistingReservation() throws Exception {
        final int reservationId = 66;
        when(gtsService.deactivateReservation(any(), anyString(), eq(Integer.toString(reservationId))))
                .thenReturn(new RestApi.RestReply<>(new Mock404HttpCallDetails(), ""));

        gtsReservationManager.deactivateReservation(reservationId);
    }

    @Test
    public void testReleaseReservation() throws Exception {
        final int reservationId = 67;
        when(gtsService.releaseReservation(any(), anyString(), eq(Integer.toString(reservationId))))
                .thenReturn(new RestApi.RestReply<>(new Mock204HttpCallDetails(), ""));

        gtsReservationManager.releaseReservation(reservationId);
    }

    @Test(expectedExceptions = GtsException.class, expectedExceptionsMessageRegExp = "A server-side error .*404.*")
    public void testReleaseNonExistingReservation() throws Exception {
        final int reservationId = 66;
        when(gtsService.releaseReservation(any(), anyString(), eq(Integer.toString(reservationId))))
                .thenReturn(new RestApi.RestReply<>(new Mock404HttpCallDetails(), ""));

        gtsReservationManager.releaseReservation(reservationId);
    }

    @Test
    public void testAddProject() throws Exception {

        GtsXmlProject project = new GtsXmlProject();
        project.setId("jfedtest");
        project.setVpnUser("user");
        project.setVpnPassword("pass");
        project.setUserLogins(Collections.singletonList("userlogin"));

        when(gtsService.addProject(any(), anyString(), eq(project.getId()), eq(project.getVpnUser()), eq(project.getVpnPassword()), eq(project.getUserLogins()), any()))
                .thenReturn(new RestApi.RestReply<String>(new MockHttpCallDetails(), project.getId()));

        String newProjectName = gtsReservationManager.addProject(project);

        assertEquals(newProjectName, project.getId());
    }
}