using be.fgov.ehealth.technicalconnector.tests.session;
using be.fgov.ehealth.technicalconnector.tests.utils;
using be.ehealth.business.mycarenetdomaincommons.domain;
using be.ehealth.businessconnector.mycarenet.memberdatav2.builders;
using be.ehealth.businessconnector.mycarenet.memberdatav2.domain;
using be.ehealth.businessconnector.mycarenet.memberdatav2.session;
using be.ehealth.businessconnector.mycarenet.memberdatav2.session.builders;
using be.ehealth.businessconnector.test.testcommons.utils;
using be.ehealth.technicalconnector.utils;
using be.fgov.ehealth.errors.core.v1;
using be.fgov.ehealth.errors.soa.v1;
using be.fgov.ehealth.mycarenet.memberdata.protocol.v1;
using be.fgov.ehealth.technicalconnector.signature.domain;
using oasis.names.tc.saml._2_0.protocol;
using org.apache.commons.io;
using javax.xml.soap;
using javax.xml.ws.soap;
using java.io;
using java.util;
using org.w3c.dom;

using NUnit.Framework;
using System;

namespace be.ehealth.businessconnector.mycarenet.memberdatav2.session.regional
{
    public abstract class AbstractMobilityImprovementIntegrationTest {



        private static String REQUEST_LOCATION_HAPPY = ".\\scenarios\\careprovider-request-happy.xml";

        private static String REQUEST_LOCATION_UNHAPPY = ".\\scenarios\\careprovider-request-unhappy.xml";

        private static String INPUT_REFERENCE = "AAA1130000";

        private MemberDataService memberDataService;

    	private BuilderStrategy encryptedStrategy;

    	private BuilderStrategy unencryptedStrategy;


	    public AbstractMobilityImprovementIntegrationTest(MemberDataService memberDataService, BuilderStrategy encryptedStrategy, BuilderStrategy unencryptedStrategy) {
	        this.memberDataService = memberDataService;
	        this.encryptedStrategy = encryptedStrategy;
	        this.unencryptedStrategy = unencryptedStrategy;
	    }

        [Test]
        public void happyConsultationWithoutEncryption() {
            happyConsultationTest(unencryptedStrategy);
        }

        [Test]
        public void happyConsultationWithEncryption() {
            happyConsultationTest(encryptedStrategy);
        }

        [Test]
        public void unhappyConsultationWithoutEncryption() {
            unhappyConsultationTest(unencryptedStrategy);
        }

        [Test]
        public void unhappyConsultationWithEncryption() {
            unhappyConsultationTest(encryptedStrategy);
        }

        private void happyConsultationTest(BuilderStrategy strategy) {
            Map testFileParams = new HashMap();
            testFileParams.put("id", INPUT_REFERENCE);
            testFileParams.put("nihii", "99627512009");
            testFileParams.put("niss", "49112002395");
            AttributeQuery attributeQuery = (AttributeQuery) FileTestUtils.toObject(testFileParams, REQUEST_LOCATION_HAPPY, typeof(AttributeQuery));
            MemberDataConsultationRequest memberDataRequest = buildRequest(strategy, attributeQuery);
            MemberDataConsultationResponse wsResponse = memberDataService.consultMemberData(memberDataRequest);
            ResponseObjectBuilder responseBuilder = ResponseObjectBuilderFactory.getResponseObjectBuilder();
            MemberDataBuilderResponse response = responseBuilder.handleConsultationResponse(wsResponse);

            verifySignature(response);
            Assert.IsNotNull(response.getResponse());
        }

        private static void verifySignature(MemberDataBuilderResponse response) {
            Map signVerificationResult = response.getSignatureVerificationResult();
            Iterator it = signVerificationResult.keySet().iterator();

            while (it.hasNext()) {
                string key = (string) it.next();
                Assert.IsTrue(((SignatureVerificationResult) signVerificationResult.get(key)).isValid(), "Errors found in the signature verification");
            }
        }

        private void unhappyConsultationTest(BuilderStrategy strategy) {
            Map testFileParams = new HashMap();
            testFileParams.put("content", "blabla");
            String requestContent = FileTestUtils.toString(testFileParams, REQUEST_LOCATION_UNHAPPY);
            MemberDataConsultationRequest memberDataRequest = buildRequest(strategy, requestContent);
            MemberDataService service = MemberDataSessionServiceFactory.getMemberDataSyncService();
            Assert.Throws<SOAPFaultException>( () => service.consultMemberData(memberDataRequest));
        }

        private MemberDataConsultationRequest buildRequest(BuilderStrategy strategy, Object content) {
            ConnectorXmlUtils.dump(content);

            // input reference and AttributeQuery ID must match
            InputReference inputReference = new InputReference(INPUT_REFERENCE);

            return strategy.build(true, inputReference, content);
        }
    }
}
