package be.fgov.ehealth.technicalconnector.tests.junit.rule.callbacks;

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

import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

import org.apache.commons.io.Charsets;
import org.junit.Assert;
import org.mockserver.mock.action.ExpectationCallback;
import org.mockserver.model.Header;
import org.mockserver.model.HttpRequest;
import org.mockserver.model.HttpResponse;
import org.mockserver.model.HttpStatusCode;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import be.fgov.ehealth.technicalconnector.tests.utils.XmlAsserter;

public class AssertSOAPQueryCallback implements ExpectationCallback {

    private static final Logger LOG = LoggerFactory.getLogger(AssertSOAPQueryCallback.class);

    private static int actualCallNumber = 1;


    private Queue<AssertStep> steps = new LinkedList<AssertStep>();

    public AssertSOAPQueryCallback(AssertStep... assertSteps) {
        this.steps.addAll(Arrays.asList(assertSteps));
    }

    @Override
    public HttpResponse handle(HttpRequest httpRequest) {
        AssertStep step = steps.poll();
        if (step == null) {
            Assert.fail("No more step to use");
        }

        String input = new String(httpRequest.getBody()
                                             .getRawBytes(), Charsets.toCharset("UTF-8"));

        if (step.getCallNumber() != 0) {
            LOG.debug("[MOCKSERVER] Verifying the order ...");
            Assert.assertEquals(step.getCallNumber(), actualCallNumber);
        }

        LOG.debug("[MOCKSERVER] Asserting ...");
        XmlAsserter.assertSimilar(step.getXmlForAssert(), input);

        LOG.debug("[MOCKSERVER] Answering ...");
        actualCallNumber++;
        return response().withHeader(new Header("Content-Type", "text/xml; charset=utf-8"))
                         .withStatusCode(HttpStatusCode.OK_200.code())
                         .withBody(step.getXmlToReturn());
    }
}