package be.ehealth.businessconnector.invoicing;

import java.util.Arrays;
import java.util.Collection;
import java.util.concurrent.TimeUnit;

import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import be.cin.mycarenet.esb.common.v2.CommonInput;
import be.cin.nip.async.generic.Post;
import be.cin.nip.async.generic.PostResponse;
import be.ehealth.business.mycarenetcommons.builders.BlobBuilder;
import be.ehealth.business.mycarenetcommons.builders.BlobBuilderFactory;
import be.ehealth.business.mycarenetcommons.builders.RequestBuilderFactory;
import be.ehealth.business.mycarenetcommons.builders.util.BlobUtil;
import be.ehealth.business.mycarenetcommons.domain.Blob;
import be.ehealth.business.mycarenetcommons.mapper.SendRequestMapper;
import be.ehealth.business.mycarenetcommons.util.WsAddressingUtil;
import be.ehealth.businessconnector.genericasync.builders.BuilderFactory;
import be.ehealth.businessconnector.genericasync.builders.ResponseObjectBuilder;
import be.ehealth.businessconnector.genericasync.mappers.CommonInputMapper;
import be.ehealth.businessconnector.genericasync.session.GenAsyncService;
import be.ehealth.businessconnector.genericasync.session.GenAsyncSessionServiceFactory;
import be.ehealth.technicalconnector.config.util.ConfigUtil;
import be.ehealth.technicalconnector.handler.domain.WsAddressingHeader;
import be.ehealth.technicalconnector.idgenerator.IdGeneratorFactory;
import be.ehealth.technicalconnector.utils.ConnectorIOUtils;
import be.ehealth.technicalconnector.utils.ConnectorXmlUtils;
import be.fgov.ehealth.mycarenet.commons.core.v2.BlobType;
import be.fgov.ehealth.technicalconnector.tests.junit.rule.SessionRule;


/**
 * Test of the operation post of the invoicing service
 * 
 * @author EHP
 */

@RunWith(Parameterized.class)
public class ParametrizedExternalScenariosIntegrationTest {

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

    private static final String PROJECT_NAME = "invoicing";

    private String requestContentLocation;

    private String mutuality;
    
    @Rule
    public SessionRule rule = SessionRule.withActiveSession().baseOn("/be.ehealth.businessconnector.invoicing.test.properties").build();

    @Parameters(name = "OA{1}: {0}")
    public static Collection<Object[]> data() {
        Object[][] data = new Object[][]{
            // OA 100 not ready yet
            // {"TFAC1SC09.509E", "100" },
            // {"TFAC1SC11.510E", "100" },
            // {"TFAC1SC12.518E", "100" },
            // {"TFAC1SC13.519E", "100" },
            // {"TFAC1SC15.520E", "100" },
            {
                "TFAC1SC09.509E", "500"
            }, {
                "TFAC1SC11.510E", "500"
            }, {
                "TFAC1SC12.518E", "500"
            }, {
                "TFAC1SC13.519E", "500"
            }, {
                "TFAC1SC15.520E", "500"
            }, {
                "TFAC1SC09.509E", "600"
            }, {
                "TFAC1SC11.510E", "600"
            }, {
                "TFAC1SC12.518E", "600"
            }, {
                "TFAC1SC13.519E", "600"
            }, {
                "TFAC1SC15.520E", "600"
            }, {
                "TFAC1SC09.509E", "900"
            }, {
                "TFAC1SC11.510E", "900"
            }, {
                "TFAC1SC12.518E", "900"
            }, {
                "TFAC1SC13.519E", "900"
            }, {
                "TFAC1SC15.520E", "900"
            }
        };
        return Arrays.asList(data);
    }

    public ParametrizedExternalScenariosIntegrationTest(String location, String mutuality) {
        requestContentLocation = location;
        this.mutuality = mutuality;
    }

    @Test
    public void performPostRequestTest() throws Exception {

        byte[] contentBytes = ConnectorIOUtils.getBytes(ConnectorIOUtils.getResourceAsStream("/examples/request/" + requestContentLocation));
        BlobBuilder bbuilder = BlobBuilderFactory.getBlobBuilder(PROJECT_NAME);

        Blob blob = bbuilder.build(contentBytes);
        blob.setMessageName("HCPFAC");

        String inputReference = IdGeneratorFactory.getIdGenerator().generateId();
        CommonInput ci = CommonInputMapper.mapCommonInputType(RequestBuilderFactory.getCommonBuilder("invoicing").createCommonInput(ConfigUtil.retrievePackageInfo("genericasync." + "invoicing"), true, inputReference));

        be.cin.types.v1.Blob det = SendRequestMapper.mapBlobToCinBlob(blob);
        BlobType blobForXades = SendRequestMapper.mapBlobToBlobType(blob);
        byte[] xades = BlobUtil.generateXades(blobForXades, "invoicing").getValue();

        Post post = BuilderFactory.getRequestObjectBuilder(PROJECT_NAME).buildPostRequest(ci, det, xades);

        LOG.debug("Send of the post request");
        GenAsyncService service = GenAsyncSessionServiceFactory.getGenAsyncService(PROJECT_NAME);

        WsAddressingHeader header = WsAddressingUtil.createHeader(mutuality, "urn:be:cin:nip:async:generic:post:msg");

        PostResponse responsePost = service.postRequest(post, header);
        ConnectorXmlUtils.dump(responsePost);

        LOG.debug("Call of handler for the post operation");
        ResponseObjectBuilder responseBuilder = BuilderFactory.getResponseObjectBuilder();
        boolean hasWarnings = responseBuilder.handlePostResponse(responsePost);
        if (hasWarnings) {
            LOG.info("The post has warnings");
        } else {
            LOG.info("The post has no warnings");
        }
    }

}
