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.technicalconnector.tests.session;
using be.fgov.ehealth.mycarenet.memberdata.protocol.v1;
using be.fgov.ehealth.technicalconnector.signature.domain;
using be.fgov.ehealth.technicalconnector.tests.junit.rule;
using be.fgov.ehealth.technicalconnector.tests.utils;
using oasis.names.tc.saml._2_0.protocol;
using org.apache.commons.io;
using java.io;
using java.util;

using NUnit.Framework;
using System;

namespace be.ehealth.businessconnector.mycarenet.memberdatav2.session {
	
	[TestFixture]
	public class PharmacyIntegrationTest : AbstractIntegrationTest {
		
		private static string REQUEST_LOCATION_HAPPY = ".\\scenarios\\pharmacy-request-happy.xml";
	
	    private static string REQUEST_LOCATION_UNHAPPY = ".\\scenarios\\pharmacy-request-unhappy.xml";
	
	    private static string RESPONSE_LOCATION_HAPPY = ".\\scenarios\\pharmacy-response-happy.xml";
	
	    private static string RESPONSE_LOCATION_UNHAPPY = ".\\scenarios\\pharmacy-response-unhappy.xml";
	
	    private static string PHARMACIST_NISS = "72070539942";
	
	    private static string PHARMACY_NIHII = "22072151001";
	    
    	static object[] testCases = {
	    	new string[]{"89-PHA-EMEH", "true", "true"},
            new string[]{"90-PHA-EMCH", "true", "true"},
            new string[]{"92-PHA-CMEH", "true", "false"},
            new string[]{"93-PHA-CMCH", "true", "false"},
            new string[]{"91-PHA-EMEB", "false", "true"},
            new string[]{"94-PHA-CMCB", "false", "false"}
	    };
	    
		public override void init() {
			java.util.Properties props = new java.util.Properties();			
        	props.put("session.environment", "acc");
        	props.put("session.professionType", "orgpharmacy");
        	props.put("session.username", "maxime");
			SessionInitializer.init(props, true, SupportedLanguages.NET.getAbbreviation());
		}
		
		[Test, TestCaseSource("testCases")]
		public void consultationTest(string id, string isHappy, string isEncrypted) {
			bool isHappyBool = Boolean.Parse(isHappy);
			
			string requestLocation;
			string responseLocation;
			
			if (isHappyBool) {
				requestLocation = REQUEST_LOCATION_HAPPY;
				responseLocation = RESPONSE_LOCATION_HAPPY;
			} else {
				requestLocation = REQUEST_LOCATION_UNHAPPY;
				responseLocation = RESPONSE_LOCATION_UNHAPPY;
			}
			
			BuilderStrategy strategy = Boolean.Parse(isEncrypted)? ENCRYPTED_STRATEGY : UNENCRYPTED_STRATEGY;
			
	        Map testFileParams = new HashMap();
	
	        testFileParams.put("id", id);
	        testFileParams.put("nihii", PHARMACY_NIHII);
	        testFileParams.put("niss", PHARMACIST_NISS);
	
	        AttributeQuery attributeQuery = (AttributeQuery) FileTestUtils.toObject(testFileParams, requestLocation, typeof(AttributeQuery));
	
	        MemberDataConsultationRequest memberDataRequest = buildRequest(id, strategy, attributeQuery);
	
	        MemberDataService service = MemberDataSessionServiceFactory.getMemberDataSyncService();
	        MemberDataConsultationResponse wsResponse = service.consultMemberData(memberDataRequest);
	
	        ResponseObjectBuilder responseBuilder = ResponseObjectBuilderFactory.getResponseObjectBuilder();
	        MemberDataBuilderResponse response = responseBuilder.handleConsultationResponse(wsResponse);
	
	        bool isValid = verifySignatures(response);
	        if (isHappyBool) Assert.IsTrue(isValid, "Signature(s) should be valid");
	        else Assert.IsFalse(isValid, "Signature(s) should be invalid");
	        
	        InputStream inStream = ConnectorIOUtils.getResourceAsStream(responseLocation);
	        String expectedresponse = ConnectorIOUtils.convertStreamToString(inStream);
	        IOUtils.closeQuietly(inStream);
	
	        byte[] details = response.getResponse();
	
	        XmlAsserter.assertSimilar(expectedresponse, System.Text.Encoding.Default.GetString(details));
	    }
		
		private bool verifySignatures(MemberDataBuilderResponse response) {
	        Map signVerifResult = response.getSignatureVerificationResult();
	
	        if (signVerifResult.isEmpty()) return false; // we should always have signatures

            Assert.AreEqual(2, signVerifResult.entrySet().size());
            Assert.NotNull(signVerifResult.get("/*[local-name() = 'Response' and namespace-uri()='urn:oasis:names:tc:SAML:2.0:protocol']/*[local-name() = 'Assertion' and namespace-uri()='urn:oasis:names:tc:SAML:2.0:assertion'][2]/*[local-name() = 'Signature' and namespace-uri()='http://www.w3.org/2000/09/xmldsig#']"));
            Assert.NotNull(signVerifResult.get("/*[local-name() = 'Response' and namespace-uri()='urn:oasis:names:tc:SAML:2.0:protocol']/*[local-name() = 'Assertion' and namespace-uri()='urn:oasis:names:tc:SAML:2.0:assertion'][3]/*[local-name() = 'Signature' and namespace-uri()='http://www.w3.org/2000/09/xmldsig#']"));
	        Iterator it = signVerifResult.keySet().iterator();
	        while (it.hasNext()) {
	        	if (!((SignatureVerificationResult)signVerifResult.get(it.next())).isValid()) return false;
	        }
	       	
			return true; // all signatures are valid
	    }
		
	}
	
}
