package be.iminds.ilabt.jfed.rspec.parser;

import be.iminds.ilabt.jfed.rspec.model.StringRspec;
import org.testng.Assert;
import org.testng.annotations.Factory;
import org.testng.annotations.Test;

import java.util.ArrayList;
import java.util.List;

/**
 * TestStringRspec
 */
public class TestStringRspec {

    @Factory
    public static Object[] createStringRspecTests() {
        List<Object> res = new ArrayList<Object>();
        res.add(new StringRspecTest(TestRspecsLibrary.rspecA));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecAstartComment));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecAtailComment));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecA_nitoschannel));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecA_comment));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecA_routablecontrolip));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecA_xen));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecWithLinkA));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecWithLinkAutoShareLan));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecB));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecC));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecCsimple));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecCsimple2));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecManifestA));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecManifestAvlan));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecManifestAcustomProxy));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecManifestAcustomProxyAndProxyLogin));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecD));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecE));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecE2));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecE3));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecE4));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecOpenflow13test));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecE5));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecE6));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecF));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecG));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecH));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecI));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecK3));
        res.add(new StringRspecTest(TestRspecsLibrary.requestWithCommandsAndBarriersStaxErrorFormat));
        res.add(new StringRspecTest(TestRspecsLibrary.omnRequestRspecExample));
        res.add(new StringRspecTest(TestRspecsLibrary.requestRspecNodeBlockStoreExtExample));
        res.add(new StringRspecTest(TestRspecsLibrary.requestRspecLinkBlockStoreExtExample));
        res.add(new StringRspecTest(TestRspecsLibrary.requestRspecLinkBestEffortExtExample));
        res.add(new StringRspecTest(TestRspecsLibrary.requestRspecLinkMultiplexingExtExample));
        res.add(new StringRspecTest(TestRspecsLibrary.requestRspecLinkInterswitchDisallowExtExample));
        res.add(new StringRspecTest(TestRspecsLibrary.requestRspecRoutablePoolExtExample));
        res.add(new StringRspecTest(TestRspecsLibrary.nitosAdvertisement));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecA_routableAddresses));
        res.add(new StringRspecTest(TestRspecsLibrary.felixRequest));
        res.add(new StringRspecTest(TestRspecsLibrary.performltrManifest));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecAwithExecuteAnsiblePlaybookA));
        res.add(new StringRspecTest(TestRspecsLibrary.rspecAwithExecuteAnsiblePlaybookB));
        return res.toArray();
    }

    public static class StringRspecTest {
        private final String rspec;

        public StringRspecTest(String rspec) {
            this.rspec = rspec;
        }

        @Test
        public void testStringRspec() throws Exception {
            StringRspec sr = new StringRspec(rspec);
            Assert.assertTrue(sr.isWellFormed(), "not wellformed: \"" + rspec + "\"");
            List<String> cmUrn = sr.getAllComponentManagerUrns();
            Assert.assertTrue(cmUrn.size() > 0, "did not find component managers in: " + rspec);
        }
    }

    @Test
    public void testStringRspecNoNS() throws Exception {
        StringRspec sr = new StringRspec(TestRspecsLibrary.rspecStringNoNS);
        Assert.assertTrue(sr.isWellFormed());
        Assert.assertFalse(sr.isValidRspec());

//        StringRspec sr = testStringRspec(TestRspecRecontructable.rspecStringNoNS);
//        List<String> cmUrns = sr.getAllComponentManagerUrns();
//        Assert.assertEquals(cmUrns.size(), 1);
//        Assert.assertEquals(cmUrns.get(0), "urn:publicid:IDN+wall3.test.ibbt.be+authority+cm");
    }

    @Test
    public void testStringRspecNamedNS() throws Exception {
        StringRspec sr = testStringRspec(TestRspecsLibrary.rspecStringNamedNS);
        List<String> cmUrns = sr.getAllComponentManagerUrns();
        Assert.assertEquals(cmUrns.size(), 1);
        Assert.assertEquals(cmUrns.get(0), "urn:publicid:IDN+wall3.test.ibbt.be+authority+cm");
    }

    @Test
    public void testStringRspecWrongNS() throws Exception {
        StringRspec sr = new StringRspec(TestRspecsLibrary.rspecStringWrongNS);
        Assert.assertTrue(sr.isWellFormed());
        Assert.assertFalse(sr.isValidRspec());

//        StringRspec sr = testStringRspec(TestRspecRecontructable.rspecStringWrongNS);
//        List<String> cmUrns = sr.getAllComponentManagerUrns();
//        Assert.assertEquals(cmUrns.size(), 1);
//        Assert.assertEquals(cmUrns.get(0), "urn:publicid:IDN+wall3.test.ibbt.be+authority+cm");
    }

    @Test
    public void testStringRspecMixedMess() throws Exception {
        StringRspec sr = new StringRspec(TestRspecsLibrary.rspecStringMixedMess);
//        Assert.assertFalse(sr.isWellFormed()); //is having elements in non defined default namespace not welformed?
//        Assert.assertFalse(sr.isValidRspec()); //is this a valid RSpec? should we parse the cms or throw an error or partially parse?

        //same here. what is good way to handle this?
        sr = new StringRspec(TestRspecsLibrary.rspecStringMixedMess2);
//        Assert.assertFalse(sr.isWellFormed());
//        Assert.assertFalse(sr.isValidRspec());



//        StringRspec sr = testStringRspec(TestRspecRecontructable.rspecStringMixedMess);
//        List<String> cmUrns = sr.getAllComponentManagerUrns();
//        Assert.assertEquals(cmUrns.size(), 2, "not all cm's found in rspecStringMixedMess: " + cmUrns);
//        Assert.assertTrue(cmUrns.contains("urn:publicid:IDN+wall3.test.ibbt.be+authority+cm"));
//        Assert.assertTrue(cmUrns.contains("urn:publicid:IDN+wall2+authority+cm"));
//
//        sr = testStringRspec(TestRspecRecontructable.rspecStringMixedMess2);
//        cmUrns = sr.getAllComponentManagerUrns();
//        Assert.assertEquals(cmUrns.size(), 2, "not all cm's found in rspecStringMixedMess2: " + cmUrns);
//        Assert.assertTrue(cmUrns.contains("urn:publicid:IDN+wall3.test.ibbt.be+authority+cm"));
//        Assert.assertTrue(cmUrns.contains("urn:publicid:IDN+wall2+authority+cm"));
    }

    public StringRspec testStringRspec(String rspec) {
        StringRspec sr = new StringRspec(rspec);
        Assert.assertTrue(sr.isWellFormed(), "not wellformed: " + rspec);
        List<String> cmUrn = sr.getAllComponentManagerUrns();
        Assert.assertTrue(cmUrn.size() > 0, "did not find component managers in: " + rspec);
        return sr;
    }

    @Test
    public void testStringRspecRecorderCommand() throws Exception {
        StringRspec sr = testStringRspec(TestRspecsLibrary.requestWithCommandsAndBarriersPreStaxFormat);
        List<String> cmUrns = sr.getAllComponentManagerUrns();
        Assert.assertEquals(cmUrns.size(), 1);
        Assert.assertEquals(cmUrns.get(0), "urn:publicid:IDN+wall2.ilabt.iminds.be+authority+cm");
    }
}
