package ru.yandex.direct.api.v5.ws.soap;

import java.io.IOException;
import java.io.InputStream;

import javax.annotation.Nullable;

import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.ws.WebServiceMessageFactory;
import org.springframework.ws.soap.saaj.SaajSoapMessageFactory;


@Component
public class SoapMessageFactory implements WebServiceMessageFactory {

    private static final String SERVICE_VARIABLE = "service";
    private static final String OPERATION_VARIABLE = "operation";
    private static final String URL_PATTERN = "/v5/{" + SERVICE_VARIABLE + "}/{" + OPERATION_VARIABLE + "}";

    private final AntPathMatcher pathMatcher;
    private final SaajSoapMessageFactory saajSoapMessageFactory;

    public SoapMessageFactory() {
        pathMatcher = new AntPathMatcher();
        pathMatcher.setCachePatterns(true);
        saajSoapMessageFactory = new SaajSoapMessageFactory();
        saajSoapMessageFactory.afterPropertiesSet();
    }

    @Override
    public SoapMessage createWebServiceMessage() {
        return new SoapMessage(
                saajSoapMessageFactory.createWebServiceMessage(),
                this::getServiceFromSoapAction,
                this::getOperationFromSoapAction);
    }

    @Override
    public SoapMessage createWebServiceMessage(InputStream inputStream) throws IOException {
        return new SoapMessage(
                saajSoapMessageFactory.createWebServiceMessage(inputStream),
                this::getServiceFromSoapAction,
                this::getOperationFromSoapAction);
    }

    @Nullable
    private String getServiceFromSoapAction(String soapAction) {
        return pathMatcher.extractUriTemplateVariables(URL_PATTERN, soapAction).get(SERVICE_VARIABLE);
    }

    @Nullable
    private String getOperationFromSoapAction(String soapAction) {
        return pathMatcher.extractUriTemplateVariables(URL_PATTERN, soapAction).get(OPERATION_VARIABLE);
    }
}
