/*
 * Copyright (c) eHealth
 */
using System;
using be.ehealth.technicalconnector.session;
using be.ehealth.technicalconnector.utils;
using ikvm.extensions;
using java.lang;
using java.util;
using NUnit.Framework;
using be.ehealth.business.common.domain;
using be.ehealth.business.kmehrcommons;
using be.ehealth.businessconnector.dmg.builders;
using be.ehealth.businessconnector.dmg.domain;
using be.ehealth.businessconnector.dmg.session;
using be.ehealth.businessconnector.dmg.util;
using be.ehealth.technicalconnector.config;
using be.ehealth.technicalconnector.config.impl;
using be.fgov.ehealth.globalmedicalfile.protocol.v1;
using be.fgov.ehealth.standards.kmehr.cd.v1;
using be.fgov.ehealth.standards.kmehr.id.v1;
using be.fgov.ehealth.standards.kmehr.schema.v1;
using be.fgov.ehealth.messageservices.core.v1;
using be.fgov.ehealth.technicalconnector.signature.domain;
using be.fgov.ehealth.technicalconnector.tests.utils;
using be.fgov.ehealth.technicalconnector.tests.session;

namespace be.ehealth.businessconnector.dmg.integration
{
	/**
	* Notify Integration Test
	* 
	* @author EHP
	* 
	*/
	[TestFixture]
	public class DmgNotificationIntegrationTest
	{
		
		[SetUp]
	    public static void init() {
	        new ConfigurationModuleXmlSec().init(null);
	        SessionInitializer.init(".\\be.ehealth.businessconnector.dmg.test.properties", SupportedLanguages.NET.getAbbreviation());
	    }
		
		[TearDown]
		public static void tearDown() {
			Session.getInstance().unloadSession();
		}
	
		[Test]
	    public void testOA300() {
	
	        Patient pI = new Patient();
	        pI.setFirstName("Madeleine");
	        pI.setLastName("De Maret");
	        pI.setMutuality("300");
	        pI.setInss("59120346292");
	        baseNotificationTest(pI, "female", null, new org.joda.time.DateTime().minusDays(1), "101076");
	    }
		
	    /**
         * This test will fail with following error if registration could not be perfomed:
         * "checking if dmg already exists : expecting 161 or 165 but was 163"
         */
		[Test]
	    public void testOA600() {
	        Patient pI = new Patient();
	        pI.setFirstName("Ajse");
	        pI.setLastName("Osmani");
	        pI.setMutuality("600");
	        pI.setInss("05041001640");
	        baseNotificationTest(pI, "female", null, new org.joda.time.DateTime().minusDays(2), "101076");
	    }
	
	    private void baseNotificationTest(Patient pI, string sex, HcpartyType dmgTargetAuthor, org.joda.time.DateTime dmgEncounterDate, string nomenclature){
            bool istest = true;

	      	DMGReferences reference = new DMGReferences(true);

	        org.joda.time.DateTime dateReference = new org.joda.time.DateTime();
	        byte[] expected = ConnectorIOUtils.getBytes(ConnectorIOUtils.getResourceAsStream(".\\templates/SendTransactionRequest.kmerhmessage.xml"));

	        MarshallerHelper kmehrRequestMarshaller = new MarshallerHelper(typeof(Kmehrmessage),typeof(Kmehrmessage));
	        Kmehrmessage request = (Kmehrmessage)kmehrRequestMarshaller.toObject(expected);
	
	
	        PersonType patient = new PersonType();
	        IDPATIENT idpatient = new IDPATIENT();
	        idpatient.setSV("1.0");
	        idpatient.setValue(pI.getInss());
	        idpatient.setS(IDPATIENTschemes.ID_PATIENT);
	        patient.getIds().add(idpatient);
	
	        if (sex != null && !sex.isEmpty()) {
	            CDSEX cdsex = new CDSEX();
	            cdsex.setSV("1.0");
	            cdsex.setS("CD-SEX");
	            cdsex.setValue(CDSEXvalues.fromValue(sex));
	            SexType sexType = new SexType();
	            sexType.setCd(cdsex);
	            patient.setSex(sexType);
	        }
	        MemberinsuranceType member = new MemberinsuranceType();
	
	        if (pI.getRegNrWithMut() != null) {
	            member.setMembership(pI.getRegNrWithMut());
	            if (pI.getMutuality() != null) {
	                IDINSURANCE id = new IDINSURANCE();
	                id.setSV("1.0");
	                id.setValue(pI.getMutuality());
	                member.setId(id);
	            }
	        }
	        if (member.getId() != null || member.getMembership() != null) {
	            patient.setInsurancymembership(member);
	        }
	        patient.setFamilyname(pI.getLastName());
	        patient.getFirstnames().add(pI.getFirstName());
	
	        FolderType folder = (FolderType)request.getFolders().get(0);
	        folder.setPatient(patient);
	        be.fgov.ehealth.standards.kmehr.schema.v1.TransactionType transaction = (be.fgov.ehealth.standards.kmehr.schema.v1.TransactionType)folder.getTransactions().get(0);
	        transaction.getAuthor().getHcparties().clear();
	
	        AuthorType author = HcPartyUtil.createAuthor(DmgConstants.PROJECT_IDENTIFIER);
	        transaction.setAuthor(author);
	        HeaderType header = request.getHeader();
	        // header.getIds().clear();
	        // //kmehrMessage zelf moet ander id hebben dan request???
	        // header.getIds().add(HcPartyUtil.createKmehrId(DmgConstants.PROJECT_IDENTIFIER));//, ref.getKmehrIdSuffix()));
	        header.getSender().getHcparties().clear();
	        header.getSender().getHcparties().addAll(author.getHcparties());
	
	        HcpartyType dmgTarget = dmgTargetAuthor;
	        if (dmgTarget == null) {
	            dmgTarget = HcPartyUtil.createProfessionalParty(SessionUtil.getNiss(), SessionUtil.getNihii11(), "persphysician");
	            dmgTarget.setFirstname(ConfigFactory.getConfigValidator().getProperty("user.firstname"));
	            dmgTarget.setFamilyname(ConfigFactory.getConfigValidator().getProperty("user.lastname"));
	        }
	        ItemType item = (ItemType) transaction.getItem().get(0);
	        ContentType content = (ContentType)item.getContents().get(0);
	        content.setHcparty(dmgTarget);
	        
			item = (ItemType) transaction.getItem().get(1);
			content = (ContentType)item.getContents().get(0);
	        content.setDate(dmgEncounterDate);
	        
	        item = (ItemType) transaction.getItem().get(2);
	        content = (ContentType)item.getContents().get(0);
	        content.getCds().clear();
	        
	        CDCONTENT cdcontent = new CDCONTENT();
	        cdcontent.setS(CDCONTENTschemes.CD_NIHDI);
	        cdcontent.setSV("1.0");
	        cdcontent.setValue(nomenclature);
	        content.getCds().add(cdcontent);
	
	
	        RequestObjectBuilder reqBuilder = RequestObjectBuilderFactory.getRequestObjectBuilder();
	        NotifyGlobalMedicalFileRequest result = reqBuilder.buildSendNotifyRequest(istest, reference, pI, dateReference, request);
	
	
	        DmgService service = DmgSessionServiceFactory.getDmgService();
	        SendResponseType resp = service.notifyGlobalMedicalFile(result);
	
	        ResponseObjectBuilder respBuilder = ResponseObjectBuilderFactory.getResponseObjectBuilder();
	        DmgBuilderResponse response = respBuilder.handleSendResponseType(resp);
	
	        Assert.AreEqual("200", response.getEhealthStatus());
	
	
	        SendTransactionResponse sendTransactionResponse = response.getSendTransactionResponse();
	        Assert.NotNull(sendTransactionResponse);
	        AcknowledgeType acknowledge = sendTransactionResponse.getAcknowledge();
	        Assert.NotNull(acknowledge);
	        java.util.List errors = acknowledge.getErrors();
	        StringBuilder errorCodesBuilder = new StringBuilder("");
	        if (errors != null && !errors.isEmpty()) {
	        	for (int i =0;i<errors.size();i++) {
	        		ErrorMyCarenetType errorType = (ErrorMyCarenetType)errors.get(i);
	                StringBuilder sb = new StringBuilder();
	                sb.append("errorCds : [");
	                for (int j = 0; j < errorType.getCds().size() ;j++) {
	                	CDERRORMYCARENET errorCd = (CDERRORMYCARENET)errorType.getCds().get(j);
	                    sb.append(" [" + errorCd.getValue()).append("] ");
	                }
	                errorCodesBuilder.append("[").append(sb.toString()).append("]");
	                sb.append("], url:[").append(errorType.getUrl());
	                sb.append("] , description:[" + errorType.getDescription() != null ? errorType.getDescription().getValue() : "empty description" + "]");

	            }
	        }
	        string errorCodes = errorCodesBuilder.toString();
	        bool alreadyExists = checkIfDmgAlreadyExists(errors);
	        if (!alreadyExists) {
	            Assert.NotNull(sendTransactionResponse.getKmehrmessage(),"kmehrMessage empty: errors:" + errorCodes);            
	        }
	        Map resultMap = response.getResult();
	        Assert.NotNull(resultMap.get(DmgBuilderResponse.RESULT_AS_BYTE));
	        Assert.NotNull(resultMap.get(DmgBuilderResponse.RESULT_EHEALTH_STATUS));
	        Assert.NotNull(resultMap.get(DmgBuilderResponse.RESULT_HAS_SIGNATURE));
	        Assert.NotNull(resultMap.get(DmgBuilderResponse.RESULT_ORGINAL));
	        Assert.NotNull(resultMap.get(DmgBuilderResponse.RESULT_SIGINATURE_VERIFICATION));
	        Assert.AreEqual("200", resultMap.get(DmgBuilderResponse.RESULT_EHEALTH_STATUS));
	        java.lang.Boolean resultHasSignature = (java.lang.Boolean) resultMap.get(DmgBuilderResponse.RESULT_HAS_SIGNATURE);
	        Assert.IsTrue(resultHasSignature.booleanValue());
	        
	        SignatureVerificationResult verificationResult = (SignatureVerificationResult) resultMap.get(DmgBuilderResponse.RESULT_SIGINATURE_VERIFICATION);
	        Assert.AreEqual(true, verificationResult.isValid());
	    }
 
 	    private bool checkIfDmgAlreadyExists(java.util.List errors) {
	        if (errors != null && !errors.isEmpty()) {
				for (int i = 0; i<errors.size() ; i++) {
					ErrorMyCarenetType error = (ErrorMyCarenetType)errors.get(i);
					CDERRORMYCARENET cderrormycarenet = (CDERRORMYCARENET)error.getCds().get(0);
					Assert.IsTrue(cderrormycarenet.getValue().Equals("161") || cderrormycarenet.getValue().Equals("165" ),"checking if dmg already exists : expecting 161 or 165 but was "+cderrormycarenet.getValue());
	            }
	            return true;
	        }
	        return false;
	    }
	}
}
