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 be.fgov.ehealth.technicalconnector.tests.utils;
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
{
	
	public abstract class AbstractCareProviderIntegrationTest : AbstractIntegrationTest {
		
		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 RESPONSE_LOCATION_HAPPY = ".\\scenarios\\careprovider-response-happy.xml";

    	private static string DEFAULT_VALUE = "BLABLA";
    	
    	private string enehID;
	
	    private string enxsID;
	
	    private string cnchID;
	
	    private string cnxsID;
    
		public AbstractCareProviderIntegrationTest(string enehID, string enxsID, string cnchID, string cnxsID) {
	        this.enehID = enehID;
	        this.enxsID = enxsID;
	        this.cnchID = cnchID;
	        this.cnxsID = cnxsID;
	    }
		
		[Test]
	    public void happyConsultationWithoutEncryption() {
	        happyConsultationTest(UNENCRYPTED_STRATEGY, cnchID);
	    }
	
	    [Test]
	    public void happyConsultationWithEncryption() {
	        happyConsultationTest(ENCRYPTED_STRATEGY, enehID);
	    }
	
	    [Test]
	    public void unhappyConsultationWithoutEncryption() {
	        unhappyConsultationTest(UNENCRYPTED_STRATEGY, cnxsID);
	    }
	
	    [Test]
	    public void unhappyConsultationWithEncryption() {
	        unhappyConsultationTest(ENCRYPTED_STRATEGY, enxsID);
	    }
	
	    private void happyConsultationTest(BuilderStrategy strategy, string inputReference) {
	        Map testFileParams = new HashMap();
	
	        testFileParams.put("id", inputReference);
	        testFileParams.put("nihii", DEFAULT_VALUE);
	        testFileParams.put("niss", DEFAULT_VALUE);
	
	        AttributeQuery attributeQuery = (AttributeQuery) FileTestUtils.toObject(testFileParams, REQUEST_LOCATION_HAPPY, typeof(AttributeQuery));
	
	        MemberDataConsultationRequest memberDataRequest = buildRequest(inputReference, strategy, attributeQuery);
	
	        MemberDataService service = MemberDataSessionServiceFactory.getMemberDataSyncService();
	        MemberDataConsultationResponse wsResponse = service.consultMemberData(memberDataRequest);
	
	        ResponseObjectBuilder responseBuilder = ResponseObjectBuilderFactory.getResponseObjectBuilder();
	        MemberDataBuilderResponse response = responseBuilder.handleConsultationResponse(wsResponse);
	
	        Map signVerifResult = response.getSignatureVerificationResult();
	        Iterator it = signVerifResult.keySet().iterator();
	        
	        while (it.hasNext()) {
	        	string key = (string) it.next();
	        	Assert.IsTrue(((SignatureVerificationResult)signVerifResult.get(key)).isValid(), "Errors found in the signature verification");
	        }
	
	        java.io.InputStream inStream = ConnectorIOUtils.getResourceAsStream(RESPONSE_LOCATION_HAPPY);
	        string expectedresponse = ConnectorIOUtils.convertStreamToString(inStream);
	        IOUtils.closeQuietly(inStream);
	
	        byte[] details = response.getResponse();
	
	        XmlAsserter.assertSimilar(expectedresponse, System.Text.Encoding.Default.GetString(details));
	    }
	
	    private void unhappyConsultationTest(BuilderStrategy strategy, string inputReference) {
	        Map testFileParams = new HashMap();
	
	        testFileParams.put("content", DEFAULT_VALUE.ToLower());
	
	        string requestContent = FileTestUtils.toString(testFileParams, REQUEST_LOCATION_UNHAPPY);
	
	        MemberDataConsultationRequest memberDataRequest = buildRequest(inputReference, strategy, requestContent);
	
	        MemberDataService service = MemberDataSessionServiceFactory.getMemberDataSyncService();
	
	        try {
	            service.consultMemberData(memberDataRequest);
	            Assert.Fail("soap fault expected");
	        } catch (SOAPFaultException sfe) {
	            checkSOAPFault(sfe);
	        }
	    }
	
	    private void checkSOAPFault(SOAPFaultException sfe) {
	        java.util.List entries = new ArrayList();
	        Iterator it = sfe.getFault().getDetail().getDetailEntries();
	        while (it.hasNext()) entries.add((DetailEntry) it.next());
	
	        Assert.IsTrue(entries.size() == 1);
	
	        MarshallerHelper helper = new MarshallerHelper(typeof(BusinessError), typeof(BusinessError));
	        BusinessError error = (BusinessError) helper.toObject((org.w3c.dom.Node) entries.get(0));
	
	        Assert.IsTrue("INVALID_DETAIL_REQUEST".Equals(error.getCode()));
	        Assert.IsTrue("MYCARENET".Equals(error.getOrigin()));
	
	        java.util.List messages = error.getMessages();
	        Assert.IsTrue(messages.size() == 1);
	
	        LocalisedStringType message = (LocalisedStringType)messages.get(0);
	        Assert.IsTrue("Detail XML structure is not valid against schema.".Equals(message.getValue()));
	    }
		
	}
	
}
