package be.ehealth.technicalconnector.utils;

import be.ehealth.technicalconnector.config.ConfigFactory;
import org.junit.Assert;
import org.junit.Test;

import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.fgov.ehealth.technicalconnector.tests.utils.LoggingUtils;

import javax.xml.transform.Result;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.StringWriter;

/**
 * @author EHP
 */
public class ConnectorXmlUtilsTest {

    @Test
    public void isXMLOneliner() {
        Assert.assertTrue(ConnectorXmlUtils.isXMLLike("<boe/>"));
    }

    @Test
    public void isXML() {
        Assert.assertTrue(ConnectorXmlUtils.isXMLLike("<boe>\n\ttest\n</boe>"));
    }

    @Test
    public void isXMLWithProcessInstruction() {
        Assert.assertTrue(ConnectorXmlUtils.isXMLLike("<?xml version=\"1.0\" encoding=\"UTF-8\" ?><boe>\ntest\n</boe>"));
    }

    @Test
    public void isNotXML() {
        Assert.assertFalse(ConnectorXmlUtils.isXMLLike("test"));
    }


    @Test(expected = Exception.class)
    public void xmlBombPreventionTransformerFactory() throws Exception {
        LoggingUtils.bootstrap();
        ConfigFactory.getConfigValidator().getProperty("bootstrap");

        String xml = "<?xml version=\"1.0\"?>\n" +
                "<!DOCTYPE lolz [\n" +
                "<!ENTITY lol \"lol\">\n" +
                "<!ENTITY lol2 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\n" +
                "<!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n" +
                "<!ENTITY lol4 \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n" +
                "<!ENTITY lol5 \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\">\n" +
                "<!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\n" +
                "<!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\n" +
                "<!ENTITY lol8 \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\n" +
                "<!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\n" +
                "]>\n" +
                "<lolz>&lol9;</lolz>";

        System.setProperty("jdk.xml.entityExpansionLimit","0");

        StreamSource streamSource = new StreamSource(new ByteArrayInputStream(xml.getBytes()));
        ConnectorXmlUtils.toString(streamSource);
    }

    @Test(expected = Exception.class)
    public void xmlBombPreventionBuilderFactory() throws Exception {
        LoggingUtils.bootstrap();
        ConfigFactory.getConfigValidator().getProperty("bootstrap");

        String xml = "<?xml version=\"1.0\"?>\n" +
                "<!DOCTYPE lolz [\n" +
                "<!ENTITY lol \"lol\">\n" +
                "<!ENTITY lol2 \"&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;&lol;\">\n" +
                "<!ENTITY lol3 \"&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;&lol2;\">\n" +
                "<!ENTITY lol4 \"&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;&lol3;\">\n" +
                "<!ENTITY lol5 \"&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;&lol4;\">\n" +
                "<!ENTITY lol6 \"&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;&lol5;\">\n" +
                "<!ENTITY lol7 \"&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;&lol6;\">\n" +
                "<!ENTITY lol8 \"&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;&lol7;\">\n" +
                "<!ENTITY lol9 \"&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;&lol8;\">\n" +
                "]>\n" +
                "<lolz>&lol9;</lolz>";

        System.setProperty("jdk.xml.entityExpansionLimit","0");

        ConnectorXmlUtils.toDocument(xml);

    }

}