package be.ehealth.businessconnector.test.mycarenet.memberdataasync.regional;

import be.ehealth.business.mycarenetdomaincommons.domain.InputReference;
import be.ehealth.businessconnector.genericasync.domain.GetRequest;
import be.ehealth.businessconnector.genericasync.domain.ProcessedGetResponse;
import be.ehealth.businessconnector.genericasync.domain.ProcessedMsgResponse;
import be.ehealth.businessconnector.mycarenet.memberdataasync.session.MemberDataService;
import be.ehealth.technicalconnector.exception.ConnectorException;
import be.ehealth.technicalconnector.utils.ConnectorIOUtils;
import be.fgov.ehealth.technicalconnector.tests.junit.rule.SessionRule;
import org.junit.Assert;
import org.junit.ClassRule;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import java.util.concurrent.TimeUnit;


@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public abstract class AbstractAsyncIntegrationTest {

    @ClassRule
    public static SessionRule rule = SessionRule.withActiveSession().forEnvironment("acc").forProfession("persotmobilityimprovement").forUser("nicolas").build();

    private static final String REQUEST_FOLDER = "/examples/memberdata/async/request/regional/";

    private static final String VALID_REQUEST = "anh-request-detail.xml";

    private static final int SLEEP_TIME = 70;

    private MemberDataService memberDataService;


    public AbstractAsyncIntegrationTest(MemberDataService memberDataService) {
        this.memberDataService = memberDataService;
    }

    @Test
    public void postMDAEncrypted() throws ConnectorException, InterruptedException {
        testValidPost(true);
    }

    @Test
    public void postMDA() throws ConnectorException, InterruptedException {
        testValidPost(false);
    }

    private void testValidPost(boolean isEncrypted) throws ConnectorException, InterruptedException {
        confirmAllMessages(getResponse()); // we clean everything first
        postRequest("AAA1130000", VALID_REQUEST, isEncrypted);
        ProcessedGetResponse<byte[]> response = getResponse();
        confirmAllMessages(response);
        verifyResponse(response);
    }

    private void verifyResponse(ProcessedGetResponse<byte[]> response) {
        Assert.assertFalse(response.getMsgResponses().isEmpty());
    }

    private void postRequest(String id, String requestXml, boolean isEncrypted) throws ConnectorException, InterruptedException {
        byte[] bytes = ConnectorIOUtils.getResourceAsByteArray(REQUEST_FOLDER + requestXml);
        InputReference inputReference = new InputReference(id);
        if (isEncrypted) {
            memberDataService.postEncryptedMDAXml(bytes, inputReference);
        } else {
            memberDataService.postMDAXml(bytes, inputReference);
        }
        waitSomeTimeBeforeProceeding();
    }

    private ProcessedGetResponse<byte[]> getResponse() throws ConnectorException {
        return memberDataService.getMDAXml(GetRequest.newBuilder().withDefaults().build());
    }

    private void confirmAllMessages(ProcessedGetResponse<byte[]> response) throws ConnectorException {
        for (ProcessedMsgResponse msgResponse : response.getMsgResponses()) {
            memberDataService.confirmMessage(msgResponse);
        }
    }

    private void waitSomeTimeBeforeProceeding() throws InterruptedException {
        TimeUnit.SECONDS.sleep(SLEEP_TIME);
    }
}
