package be.iminds.ilabt.jfed.lowlevel.api.test;

import be.iminds.ilabt.jfed.log.Logger;
import be.iminds.ilabt.jfed.lowlevel.GeniUser;
import be.iminds.ilabt.jfed.lowlevel.authority.AuthorityFinder;

import be.iminds.ilabt.jfed.lowlevel.connection.JFedConnectionProvider;
import be.iminds.ilabt.jfed.preferences.JFedPreferences;
import be.iminds.ilabt.jfed.testing.base.ApiTest;
import be.iminds.ilabt.jfed.testing.base.ApiTestResult;
import be.iminds.ilabt.jfed.util.TargetAuthority;
import org.slf4j.LoggerFactory;

import static org.testng.Assert.*;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class CommonAMTestTest {
    private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(CommonAMTestTest.class);

    private String nonWellFormedRspec = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
            "<rspec xmlns=\"http://www.geni.net/resources/rspec/3\"\n" +
            "    generated=\"2015-09-16T16:13:20.521+02:00\" generated_by=\"omnlib\" type=\"manifest\"\n" +
            "    <node\n" +
            "        client_id=\"f4f-demo-gent-2015\" component_id=\"urn:publicid:IDN+localhost+node+http%3A%2F%2Flocalhost%2Fresource%2FMotorGarage-1\"\n" +
            "        component_manager_id=\"urn:publicid:IDN+localhost+authority+cm\"\n" +
            "        sliver_id=\"urn:publicid:IDN+localhost+sliver+http%3A%2F%2Flocalhost%2Fresource%2FMotorGarage-1%2Fb5925e92-9c2f-4898-83aa-0ce92abf7d61\">\n" +
            "        <ns4:reservation reservationState=\"geni_provisioned\"/>\n" +
            "        <ns6:geni_sliver_info state=\"Uncompleted\"/>\n" +
            "        <ns2:sliver_type/>\n" +
            "    </node>\n" +
            "</rspec>";
    private String nonValidRspec = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
            "<rspec \n" +
            "    generated=\"2015-09-16T16:13:20.521+02:00\" generated_by=\"omnlib\" type=\"manifest\"\n" +
            "    <node\n" +
            "        client_id=\"f4f-demo-gent-2015\" component_id=\"urn:publicid:IDN+localhost+node+http%3A%2F%2Flocalhost%2Fresource%2FMotorGarage-1\"\n" +
            "        component_manager_id=\"urn:publicid:IDN+localhost+authority+cm\"\n" +
            "        sliver_id=\"urn:publicid:IDN+localhost+sliver+http%3A%2F%2Flocalhost%2Fresource%2FMotorGarage-1%2Fb5925e92-9c2f-4898-83aa-0ce92abf7d61\">\n" +
            "        <sliver_type/>\n" +
            "    </node>\n" +
            "</rspec>";
    private String nonEmptyValidRspecAlex = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
            "<ns2:rspec \n" +
            "    generated=\"2015-09-16T16:13:20.521+02:00\" generated_by=\"omnlib\" type=\"manifest\"\n" +
            "    xmlns=\"http://jfed.iminds.be/proxy/1.0\"\n" +
            "    xmlns:ns6=\"http://groups.geni.net/exogeni/attachment/wiki/RspecExtensions/sliver-info/1\"\n" +
            "    xmlns:ns5=\"http://groups.geni.net/exogeni/attachment/wiki/RspecExtensions/slice-info/1\"\n" +
            "    xmlns:ns7=\"http://www.geni.net/resources/rspec/ext/postBootScript/1\"\n" +
            "    xmlns:ns2=\"http://www.geni.net/resources/rspec/3\"\n" +
            "    xmlns:ns4=\"http://demo.fiteagle.org/reservation\"\n" +
            "    xmlns:ns3=\"http://monitoring.service.tu-berlin.de/monitoring\">\n" +
            "    <ns2:node\n" +
            "        client_id=\"f4f-demo-gent-2015\" component_id=\"urn:publicid:IDN+localhost+node+http%3A%2F%2Flocalhost%2Fresource%2FMotorGarage-1\"\n" +
            "        component_manager_id=\"urn:publicid:IDN+localhost+authority+cm\"\n" +
            "        sliver_id=\"urn:publicid:IDN+localhost+sliver+http%3A%2F%2Flocalhost%2Fresource%2FMotorGarage-1%2Fb5925e92-9c2f-4898-83aa-0ce92abf7d61\">\n" +
            "        <ns4:reservation reservationState=\"geni_provisioned\"/>\n" +
            "        <ns6:geni_sliver_info state=\"Uncompleted\"/>\n" +
            "        <ns2:sliver_type/>\n" +
            "    </ns2:node>\n" +
            "</ns2:rspec>";
    private String emptyValidRspecAlex = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n" +
            "<ns2:rspec \n" +
            "    generated=\"2015-09-16T16:13:20.521+02:00\" generated_by=\"omnlib\" type=\"manifest\"\n" +
            "    xmlns=\"http://jfed.iminds.be/proxy/1.0\"\n" +
            "    xmlns:ns6=\"http://groups.geni.net/exogeni/attachment/wiki/RspecExtensions/sliver-info/1\"\n" +
            "    xmlns:ns5=\"http://groups.geni.net/exogeni/attachment/wiki/RspecExtensions/slice-info/1\"\n" +
            "    xmlns:ns7=\"http://www.geni.net/resources/rspec/ext/postBootScript/1\"\n" +
            "    xmlns:ns2=\"http://www.geni.net/resources/rspec/3\"\n" +
            "    xmlns:ns4=\"http://demo.fiteagle.org/reservation\"\n" +
            "    xmlns:ns3=\"http://monitoring.service.tu-berlin.de/monitoring\">\n" +
            "</ns2:rspec>";
    public static final String rspecA =
            "<rspec type=\"request\" generated=\"2013-01-16T14:20:39Z\" " +
                    "xsi:schemaLocation=\"http://www.geni.net/resources/rspec/3 http://www.geni.net/resources/rspec/3/request.xsd \" " +
                    "xmlns:client=\"http://www.protogeni.net/resources/rspec/ext/client/1\" " +
                    "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
                    "xmlns=\"http://www.geni.net/resources/rspec/3\">\n" +
                    "  <node client_id=\"PC\" component_manager_id=\"urn:publicid:IDN+wall3.test.ibbt.be+authority+cm\" exclusive=\"true\">\n" +
                    "    <sliver_type name=\"raw-pc\"/>\n" +
                    "  </node>\n" +
                    "  <node client_id=\"PC5\" component_manager_id=\"urn:publicid:IDN+wall3.test.ibbt.be+authority+cm\" exclusive=\"false\">\n" +
                    "    <sliver_type name=\"test\"/>\n" +
                    "  </node>\n" +
                    "</rspec>\n";
    public final static String advertisementA = "<rspec type=\"advertisement\"\n" +
            "    xmlns=\"http://www.geni.net/resources/rspec/3\"\n" +
            "    xmlns:ns2=\"http://hpn.east.isi.edu/rspec/ext/stitch/0.1/\"\n" +
            "    xmlns:ns3=\"http://www.protogeni.net/resources/rspec/ext/emulab/1\"\n" +
            "    xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.geni.net/resources/rspec/3 http://www.geni.net/resources/rspec/3/ad.xsd http://hpn.east.isi.edu/rspec/ext/stitch/0.1/ http://hpn.east.isi.edu/rspec/ext/stitch/0.1/stitch-schema.xsd http://www.protogeni.net/resources/rspec/ext/emulab/1 http://www.protogeni.net/resources/rspec/ext/emulab/1/ptop_extension.xsd\">\n" +
            "    <node\n" +
            "        component_id=\"urn:publicid:IDN+exogeni.net:osfvmsite+node+orca-vm-cloud\"\n" +
            "        component_manager_id=\"urn:publicid:IDN+exogeni.net:osfvmsite+authority+am\"\n" +
            "        component_name=\"orca-vm-cloud\" exclusive=\"false\">\n" +
            "        <location country=\"Unspecified\" latitude=\"37.87631\" longitude=\"-122.25003\"/>\n" +
            "        <sliver_type name=\"XOSmall\"/>\n" +
            "        <sliver_type name=\"XOMedium\"/>\n" +
            "        <sliver_type name=\"XOLarge\"/>\n" +
            "        <hardware_type name=\"orca-vm-cloud\">\n" +
            "            <ns3:node_type type_slots=\"112\"/>\n" +
            "        </hardware_type>\n" +
            "        <available now=\"true\"/>\n" +
            "        <interface\n" +
            "            component_id=\"urn:publicid:IDN+exogeni.net:osfvmsite+interface+OSF:ExoGeni:TenGigabitEthernet:1:ethernet\" role=\"experimental\"/>\n" +
            "        <interface\n" +
            "            component_id=\"urn:publicid:IDN+exogeni.net:osfvmsite+interface+OSF:ExoGeni:TengigabitEthernet:2:ethernet\" role=\"experimental\"/>\n" +
            "    </node>\n" +
            "</rspec>\n";

    @org.testng.annotations.Test
    public void testIsEmptyRspec() throws Exception {
        assertTrue(CommonAMTest.isEmptyRspec(null, emptyValidRspecAlex));
        assertFalse(CommonAMTest.isEmptyRspec(null, nonEmptyValidRspecAlex));
        assertFalse(CommonAMTest.isEmptyRspec(null, rspecA));
        assertFalse(CommonAMTest.isEmptyRspec(null, advertisementA));
    }

    @org.testng.annotations.Test(expectedExceptions = RuntimeException.class)
    public void testIsEmptyRspec2a() throws Exception {
        boolean res = CommonAMTest.isEmptyRspec(getDummyApiTest(), nonValidRspec);
        System.out.println("Should not have been "+res);
    }

    @org.testng.annotations.Test(expectedExceptions = RuntimeException.class)
    public void testIsEmptyRspec2b() throws Exception {
        boolean res = CommonAMTest.isEmptyRspec(getDummyApiTest(), nonWellFormedRspec);
        System.out.println("Should not have been "+res);
    }


    public ApiTest getDummyApiTest() {
        ApiTest test = new ApiTest(null/*logger*/, null/* testedAuthority*/, null/* user*/, null/* connectionProvider*/,
                null/* testbedInfoSource*/, null/* authorityFinder*/, null/* jFedPreferences*/) {
            @Override
            protected String getTestDescription() {
                return "dummy";
            }

            @Override
            public void setUp() {
                setErrorsFatal();
                this.currentTestResult = new ApiTestResult.ApiTestMethodResult();
            }
        };
        try {
            test.setUp();
        } catch (Exception e) {
            //ignore
        }
        return test;
    }

    @org.testng.annotations.Test(expectedExceptions = AssertionError.class)
    public void testTestValidGeni3ManifestRspec1a() throws Exception {
        int res = CommonAMTest.testValidGeni3ManifestRspec(getDummyApiTest(), rspecA);
        System.out.println("Should not have been "+res);
    }
    @org.testng.annotations.Test(expectedExceptions = AssertionError.class)
    public void testTestValidGeni3ManifestRspec1b() throws Exception {
        int res = CommonAMTest.testValidGeni3ManifestRspec(getDummyApiTest(), advertisementA);
        System.out.println("Should not have been "+res);
    }
    @org.testng.annotations.Test(expectedExceptions = AssertionError.class)
    public void testTestValidGeni3ManifestRspec1c() throws Exception {
        int res = CommonAMTest.testValidGeni3ManifestRspec(getDummyApiTest(), nonValidRspec);
        System.out.println("Should not have been "+res);
    }

    @org.testng.annotations.Test(expectedExceptions = AssertionError.class)
    public void testTestValidGeni3ManifestRspec1d() throws Exception {
        int res = CommonAMTest.testValidGeni3ManifestRspec(getDummyApiTest(), nonWellFormedRspec);
        System.out.println("Should not have been "+res);
    }

    @org.testng.annotations.Test
    public void testTestValidGeni3ManifestRspec2() throws Exception {
        assertThat(CommonAMTest.testValidGeni3ManifestRspec(getDummyApiTest(), emptyValidRspecAlex), equalTo(0));
        assertThat(CommonAMTest.testValidGeni3ManifestRspec(getDummyApiTest(), nonEmptyValidRspecAlex), equalTo(1));
    }


    @org.testng.annotations.Test(expectedExceptions = AssertionError.class)
    public void testTestValidGeni3AdvertisementRspec1a() throws Exception {
        int res = CommonAMTest.testValidGeni3AdvertisementRspec(getDummyApiTest(), emptyValidRspecAlex);
        System.out.println("Should not have been "+res);
    }
    @org.testng.annotations.Test(expectedExceptions = AssertionError.class)
    public void testTestValidGeni3AdvertisementRspec1b() throws Exception {
        int res = CommonAMTest.testValidGeni3AdvertisementRspec(getDummyApiTest(), nonEmptyValidRspecAlex);
        System.out.println("Should not have been "+res);
    }
    @org.testng.annotations.Test(expectedExceptions = AssertionError.class)
    public void testTestValidGeni3AdvertisementRspec1c() throws Exception {
        int res = CommonAMTest.testValidGeni3AdvertisementRspec(getDummyApiTest(), rspecA);
        System.out.println("Should not have been "+res);
    }
    @org.testng.annotations.Test(expectedExceptions = AssertionError.class)
    public void testTestValidGeni3AdvertisementRspec1d() throws Exception {
        int res = CommonAMTest.testValidGeni3AdvertisementRspec(getDummyApiTest(), nonValidRspec);
        System.out.println("Should not have been "+res);
    }
    @org.testng.annotations.Test(expectedExceptions = AssertionError.class)
    public void testTestValidGeni3AdvertisementRspec1e() throws Exception {
        int res = CommonAMTest.testValidGeni3AdvertisementRspec(getDummyApiTest(), nonWellFormedRspec);
        System.out.println("Should not have been "+res);
    }

    @org.testng.annotations.Test
    public void testTestValidGeni3AdvertisementRspec2() throws Exception {
        assertThat(CommonAMTest.testValidGeni3AdvertisementRspec(getDummyApiTest(), advertisementA), equalTo(1));
    }
}