package be.ehealth.technicalconnector.handler;

import be.ehealth.technicalconnector.config.ConfigFactory;
import be.ehealth.technicalconnector.config.impl.ConfigurationFake;
import be.ehealth.technicalconnector.ws.impl.SOAPMessageContextImpl;
import be.fgov.ehealth.technicalconnector.tests.junit.rule.ConfigurationFakeRule;
import be.fgov.ehealth.technicalconnector.tests.junit.rule.LoggingRule;
import be.fgov.ehealth.technicalconnector.tests.junit.rule.RestoreSystemProperties;
import be.fgov.ehealth.technicalconnector.tests.utils.LoggingUtils;
import org.junit.*;
import org.junit.rules.TestRule;

import javax.xml.soap.MessageFactory;
import javax.xml.soap.SOAPException;
import javax.xml.soap.SOAPMessage;
import javax.xml.ws.handler.soap.SOAPMessageContext;
import java.util.regex.Pattern;

public class UserAgentHandlerTest {

    @Rule
    public ConfigurationFakeRule configurationFakeRule = new ConfigurationFakeRule();

    @Rule
    public final TestRule restoreSystemProperties = new RestoreSystemProperties();

    @ClassRule
    public static LoggingRule logging = LoggingRule.with().consoleAppender().build();

    @Test
    public void withoutSoftwarePrefix() throws Exception {
        String[] header = invoke();
        Assert.assertEquals(1, header.length);
        Assert.assertTrue(Pattern.compile("eHealthTechnical/.*").matcher(header[0]).matches());

    }

    @Test
    public void withValidSoftwarePrefix() throws Exception {
        configurationFakeRule.setProperty("be.ehealth.technicalconnector.handler.mimeheaders.user-agent.prefix", "UserAgentTest/1.0.0-rc");

        String[] header = invoke();
        Assert.assertEquals(1, header.length);
        Assert.assertTrue(Pattern.compile("UserAgentTest/1.0.0-rc eHealthTechnical/.*").matcher(header[0]).matches());

    }

    @Test
    public void withValidMultipleSoftwarePrefix() throws Exception {
        configurationFakeRule.setProperty("be.ehealth.technicalconnector.handler.mimeheaders.user-agent.prefix", "Client/1.0.0-rc Platform/6.6.6");

        String[] header = invoke();
        Assert.assertEquals(1, header.length);
        Assert.assertTrue(Pattern.compile("Client/1.0.0-rc Platform/6.6.6 eHealthTechnical/.*").matcher(header[0]).matches());

    }

    @Test
    public void withInValidSoftwarePrefix() throws Exception {
        configurationFakeRule.setProperty("be.ehealth.technicalconnector.handler.mimeheaders.user-agent.prefix", "inv@lilid/1.0.0-rc");

        String[] header = invoke();
        Assert.assertEquals(1, header.length);
        Assert.assertTrue(Pattern.compile("eHealthTechnical/.*").matcher(header[0]).matches());

    }

    @Test
    public void withInValidMultipleSoftwarePrefix() throws Exception {
        configurationFakeRule.setProperty("be.ehealth.technicalconnector.handler.mimeheaders.user-agent.prefix", "Client/1.0.0-rc Pl@tform/6.6.6");

        String[] header = invoke();
        Assert.assertEquals(1, header.length);
        Assert.assertTrue(Pattern.compile("eHealthTechnical/.*").matcher(header[0]).matches());

    }

    @Test
    public void withValidMultipleSoftwarePrefixCustomRegex() throws Exception{
        System.setProperty("be.ehealth.technicalconnector.handler.mimeheaders.user-agent.parts-regex","[a-z@]*\\/[0-9.]*");
        configurationFakeRule.setProperty("be.ehealth.technicalconnector.handler.mimeheaders.user-agent.prefix", "client/1.0.0 pl@tform/6.6.6");

        String[] header = invoke();
        Assert.assertEquals(1, header.length);
        Assert.assertTrue(Pattern.compile("client/1.0.0 pl@tform/6.6.6 eHealthTechnical/.*").matcher(header[0]).matches());


    }

    private String[] invoke() throws SOAPException {
        MessageFactory mf = MessageFactory.newInstance();

        SOAPMessage soapMessage = mf.createMessage();
        SOAPMessageContext context = new SOAPMessageContextImpl(soapMessage);

        new UserAgentHandler().handleOutbound(context);

        return context.getMessage().getMimeHeaders().getHeader("User-Agent");
    }

}