package be.fgov.ehealth.technicalconnector.tests.server.callback;

import org.mockserver.mock.action.ExpectationCallback;
import org.mockserver.model.HttpResponse;
import org.mockserver.model.HttpStatusCode;

import java.io.PrintWriter;
import java.io.StringWriter;

import static org.mockserver.model.HttpResponse.response;

public abstract class AbstractExpectationCallback implements ExpectationCallback {

    protected static HttpResponse internalError(String content, Exception... excepts) {

        StringWriter sb = new StringWriter();
        sb.append("<SOAP-ENV:Fault>");
        sb.append("<faultcode>SOAP-ENV:Server</faultcode>");
        sb.append("<faultstring>");
        sb.append("<![CDATA[")
                .append(content)
                .append("]]>");
        sb.append("</faultstring>");
        sb.append("<detail>");
        sb.append("<![CDATA[");
        for (Exception e : excepts) {
            e.printStackTrace(new PrintWriter(sb));
        }
        sb.append("]]>");
        sb.append("</detail>");
        sb.append("</SOAP-ENV:Fault>");
        return wrapSOAPEnvelope(sb.toString(), HttpStatusCode.INTERNAL_SERVER_ERROR_500);

    }

    protected static HttpResponse wrapSOAPEnvelope(String content, HttpStatusCode status) {
        StringWriter sb = new StringWriter();
        sb.append("<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"><SOAP-ENV:Body>");
        sb.append(content);
        sb.append("</SOAP-ENV:Body></SOAP-ENV:Envelope>");
        return response().withStatusCode(status.code()).withHeader("Content-Type","text/xml")
                .withBody(sb.toString());
    }

    protected static String stripNonValidXMLCharacters(String in) {
        StringBuffer out = new StringBuffer(); // Used to hold the output.
        char current; // Used to reference the current character.

        if (in == null || ("".equals(in)))
            return ""; // vacancy test.
        for (int i = 0; i < in.length(); i++) {
            current = in.charAt(i); // NOTE: No IndexOutOfBoundsException caught here; it should not happen.
            if ((current == 0x9) || (current == 0xA) || (current == 0xD) || ((current >= 0x20) && (current <= 0xD7FF)) || ((current >= 0xE000) && (current <= 0xFFFD)) || ((current >= 0x10000) && (current <= 0x10FFFF)))
                out.append(current);
        }
        return out.toString();
    }
}
