/*
 * Copyright (c) eHealth
 */
using System;
using be.fgov.ehealth.technicalconnector.tests.session;
using java.lang;
using java.util;
using be.ehealth.technicalconnector.idgenerator;
using be.ehealth.technicalconnector.utils;
using be.fgov.ehealth.hubservices.core.v3;
using NUnit.Framework;
using org.joda.time;
using be.ehealth.businessconnector.hubv3.builders;
using be.ehealth.businessconnector.hubv3.service;
using be.ehealth.businessconnector.hubv3.session;
using be.ehealth.businessconnector.hubv3.helpers;
using be.ehealth.technicalconnector.exception;
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.ehealth.technicalconnector.config;
using be.ehealth.technicalconnector.config.impl;
using be.ehealth.technicalconnector.session;
using be.fgov.ehealth.technicalconnector.tests.utils;
using be.ehealth.business.intrahubcommons.exception;
using be.ehealth.business.kmehrcommons.helper;
using be.ehealth.businessconnector.testcommons;
using org.apache.commons.lang;
using be.ehealth.business.common.domain;
using org.apache.commons.collections;

namespace be.ehealth.businessconnector.hubv3.session
{
	/**
	 * Integration test for {@link HubServiceComplete}
	 * 
	 * @author EHP
	 * 
	 */
	[TestFixture]
	public class WalkThroughRswIntegrationTest
	{
	    
	    private static string URI_TRANSACTION = "RSWID";

	    private static HubService hubService;

	    private static Configuration technicalConfig;

	    private static Properties props;

	    private static string transactionId;
	    
	    private static string transactionSetId;
        
        private static int latestMedicationSchemeVersion;
        
        private static HubTestHelper helper;


	    [SetUp]
	    public static void initHubServiceCompleteIntegrationTest() {
		    SessionInitializer.init(".\\be.ehealth.businessconnector.intrahubv3.test.properties", SupportedLanguages.NET.getAbbreviation());
		    technicalConfig = ConfigFactory.getConfigValidator().getConfig();
		    props = TestPropertiesLoader.getProperties(".\\be.ehealth.businessconnector.intrahubv3.test.properties");
		    new ConfigurationModuleProxy().init(technicalConfig);
		    HubConfigRsw.initConfig();
		    hubService = HubSessionServiceFactory.getHubService();
		    helper = new HubTestHelper("rsw", new Patient.Builder().withFirstName(HubConfigRsw.PATIENT_FIRSTNAME).withFamilyName(HubConfigRsw.PATIENT_LASTNAME).withInss(HubConfigRsw.PATIENT_NISS).build());
		    
	    }


        [TearDown]
        public void tearDownIntrahubSession() {
            Session.getInstance().unloadSession();
        }


        [Test]
        public void _010_putHcPartyConsent() {
            ConsentHCPartyType consent = new ConsentHCPartyType();
            consent.setAuthor(helper.createAuthor());
            consent.setHcparty(helper.createHcPartyIdProfessional());
            consent.setRevokedate(new org.joda.time.DateTime());
            consent.setSigndate(new org.joda.time.DateTime());
            PutHCPartyConsentResponse putHCPartyConsent = hubService.putHCPartyConsent(consent);
    
            java.util.List errors = putHCPartyConsent.getAcknowledge().getErrors();
            Assert.IsTrue(errors.isEmpty() || StringUtils.contains(((CDERROR) ((ErrorType) errors.get(0)).getCds().get(0)).getValue(), "PERHCP.CONSENT.EXISTS"), ErrorTypeManagement.printErrors(errors));
        }

        [Test]
        public void _020_putPatient() {
            PersonType person = helper.createPatient();
            PutPatientResponse putPatientResponse = hubService.putPatient(person);
    
            XmlAsserter.assertSimilar(helper.expectedResponse("PutPatient"), ConnectorXmlUtils.toString(putPatientResponse));
        }
    
        [Test]
        public void _030_getPatient() {
            GetPatientResponse getPatientResponse = hubService.getPatient(helper.createPatientIdType());
    
            XmlAsserter.assertSimilar(helper.expectedResponse("GetPatient"), ConnectorXmlUtils.toString(getPatientResponse));
        }
    
        [Test]
        public void _040_putPatientConsent() {
            PutPatientConsentResponse putPatientConsent = hubService.putPatientConsent(helper.createConsentType());
   
            XmlAsserter.assertSimilar(helper.expectedResponse("PutPatientConsent"), ConnectorXmlUtils.toString(putPatientConsent));

        }
    
        [Test]
        public void _050_putTherapeuticLink() {
            TherapeuticLinkType therapeuticLink = helper.createTherapeuticLinkType();
            PutTherapeuticLinkResponse putTherapeuticLinkResponse = hubService.putTherapeuticLink(therapeuticLink);
    
            XmlAsserter.assertSimilar(helper.expectedResponse("PutTherapeuticLink"), ConnectorXmlUtils.toString(putTherapeuticLinkResponse));
        }

        [Test]
        public void _060_putTransaction() {
            Kmehrmessage kmehrmessage = helper.createPutTransactionMessageWithLocalId();
            
            PutTransactionResponse putTransaction = hubService.putTransaction(kmehrmessage);
            
            // Retrieve the local id for later use
            java.util.List idkmehrs = (java.util.List) putTransaction.getTransaction().getIds();
            transactionId = retrieveLocalId(idkmehrs);

            XmlAsserter.assertSimilar(helper.expectedResponse("PutTransaction"), ConnectorXmlUtils.toString(putTransaction));
        }

        [Test]
        public void _070_getPatientConsent() {
            GetPatientConsentResponse patientConsentResponse = hubService.getPatientConsent(helper.createSelectGetPatientConsentType());
    
            XmlAsserter.assertSimilar(helper.expectedResponse("GetPatientConsent"), ConnectorXmlUtils.toString(patientConsentResponse));
        }
    
        [Test]
        public void _080_getTherapeuticLink() {
            GetTherapeuticLinkResponse getResponse = hubService.getTherapeuticLink(helper.createSelectGetHCPartyPatientConsentType());
    
            XmlAsserter.assertSimilar(helper.expectedResponse("GetTherapeuticLink"), ConnectorXmlUtils.toString(getResponse));
        }

        [Test]
        public void _090_getTransactionList() {
            PatientIdType patientId = helper.createPatientIdType();
            GetTransactionListResponse transactionListResponse = hubService.getTransactionList(patientId, LocalSearchType.GLOBAL, helper.createTransactionWithPeriodType());
            
            // retrieve a medicationscheme for later use
            java.util.List transactionSummaryTypes = transactionListResponse.getKmehrheader().getFolder().getTransactions();
            for (int i = 0; i<transactionSummaryTypes.size(); i++) {
            	TransactionSummaryType transactionSummaryType = (TransactionSummaryType) transactionSummaryTypes.get(i);
            	java.util.List cdtransactions = (java.util.List) transactionSummaryType.getCds();
                for (int j = 0; j<cdtransactions.size(); j++) {
                    CDTRANSACTION cdtransaction = (CDTRANSACTION) cdtransactions.get(j);
                    if (CDTRANSACTIONschemes.CD_HUBSERVICE.equals(cdtransaction.getS()) && "gettransactionset".Equals(cdtransaction.getValue())) {
                        java.util.List idkmehrs = (java.util.List) transactionSummaryType.getIds();
                        for (int k = 0; k<idkmehrs.size(); k++) {
                            IDKMEHR idkmehr = (IDKMEHR) idkmehrs.get(k);
                            if (IDKMEHRschemes.LOCAL.equals(idkmehr.getS())) {
                                transactionSetId = idkmehr.getValue();
                                break;
                            }
                        }
                    }
                }
            }  
                        
            Assert.IsNotNull(transactionListResponse.getKmehrheader(), "Kmehrheader should be present");
            Assert.IsTrue(CollectionUtils.isNotEmpty(transactionListResponse.getKmehrheader().getFolder().getTransactions()), "Transaction list should not be empty");
        }

        [Test]
        public void _100_getTransaction() {
            PatientIdType patientId = helper.createPatientIdType();
            GetTransactionResponse transactionResponse = hubService.getTransaction(patientId, helper.createTransactionBaseType("RSWID", transactionId));

            XmlAsserter.assertSimilar(helper.expectedResponse("GetTransaction"), ConnectorXmlUtils.toString(transactionResponse));
        }

        [Test]
        public void _110_revokeTransaction() {
            RevokeTransactionResponse revokeTransaction = hubService.revokeTransaction(helper.createPatientIdType(), helper.createTransactionBaseType(URI_TRANSACTION, transactionId));

            XmlAsserter.assertSimilar(helper.expectedResponse("RevokeTransaction"), ConnectorXmlUtils.toString(revokeTransaction));
        }
        
        [Test]
        public void _120_getLastestUpdate() {
            GetLatestUpdateResponse latestUpdateResponse = hubService.getLatestUpdate(helper.createSelectGetLatestUpdateType());
            latestMedicationSchemeVersion = helper.getLatestMedicationSchemeVersion(latestUpdateResponse).intValue();

            XmlAsserter.assertSimilar(helper.expectedResponse("GetLatestUpdate"), ConnectorXmlUtils.toString(latestUpdateResponse));
        }

        [Test]
        public void _130_putTransactionSet() {
            Kmehrmessage kmehrmessage = helper.createTransactionSetMessage(latestMedicationSchemeVersion, transactionSetId);
            
            PutTransactionSetResponse putTransactionSet = hubService.putTransactionSet(kmehrmessage);
            
            XmlAsserter.assertSimilar(helper.expectedResponse("PutTransactionSet"), ConnectorXmlUtils.toString(putTransactionSet));
        }

        [Test]
        public void _140_getTransactionSet() {
            PatientIdType patientId = helper.createPatientIdType();

        	GetTransactionSetResponse transactionSetResponse = hubService.getTransactionSet(patientId, helper.createTransactionBaseType(URI_TRANSACTION, transactionSetId));

            XmlAsserter.assertSimilar(helper.expectedResponse("GetTransactionSet"), ConnectorXmlUtils.toString(transactionSetResponse));
        }

	    [Test]
        [Ignore("Not implemented by RSW")]
        public void _160_declareTransaction() {
            KmehrHeaderDeclareTransaction kmehrHeader = new KmehrHeaderDeclareTransaction();
            be.fgov.ehealth.hubservices.core.v3.FolderType folder = new be.fgov.ehealth.hubservices.core.v3.FolderType();
            PatientIdType patient = helper.createPatientIdType();
    
            TransactionSummaryType transaction = new TransactionSummaryType();
            AuthorType author = helper.createAuthor();
            transaction.setAuthor(author);
            CDTRANSACTION cdTransaction = new CDTRANSACTION();
            cdTransaction.setS(CDTRANSACTIONschemes.CD_TRANSACTION);
            cdTransaction.setSV("1.0");
            cdTransaction.setValue("sumehr");
            transaction.getCds().add(cdTransaction);
            transaction.setDate(new org.joda.time.DateTime());
            transaction.getIds().add(helper.createMessageId(HubConfigCommon.MESSAGE_ID));
            transaction.setIscomplete(true);
            transaction.setIsvalidated(true);
            transaction.setTime(new org.joda.time.DateTime());
            transaction.setRecorddatetime(new org.joda.time.DateTime());
    
            folder.setTransaction(transaction);
            folder.setPatient(patient);
            kmehrHeader.setFolder(folder);
            hubService.declareTransaction(kmehrHeader);
        }
    
        [Test]
        [Ignore("Not implemented by RSW")]
        public void _170_requestPublication() {
            hubService.requestPublication(helper.createPatientIdType(), helper.createTransactionWithPeriodType(), "");
        }
    
        [Test]
        public void _180_putHcParty() {
            PutHCPartyResponse putHCPartyResponse = hubService.putHCParty(helper.createHcPartyAdaptedType());
    
            XmlAsserter.assertSimilar(helper.expectedResponse("PutHcParty"), ConnectorXmlUtils.toString(putHCPartyResponse));
        }
    
        [Test]
        public void _190_getHcParty() {
            HCPartyIdType hcParty = helper.createHcPartyIdProfessional();
            GetHCPartyResponse getHCPartyResponse = hubService.getHCParty(hcParty);
    
            XmlAsserter.assertSimilar(helper.expectedResponse("GetHcParty"), ConnectorXmlUtils.toString(getHCPartyResponse));
        }
    
        [Test]
        public void _200_getHcPartyConsent() {
            HCPartyIdType hcParty = helper.createHcPartyIdProfessional();
            GetHCPartyConsentResponse getHCPartyConsentResponse = hubService.getHCPartyConsent(hcParty);
    
            XmlAsserter.assertSimilar(helper.expectedResponse("GetHcPartyConsent"), ConnectorXmlUtils.toString(getHCPartyConsentResponse));
        }
        
        [Test]
        public void _210_revokeHcPartyConsent() {
            ConsentHCPartyType consent = new ConsentHCPartyType();
            consent.setAuthor(helper.createAuthor());
            consent.setHcparty(helper.createHcPartyIdProfessional());
            consent.setRevokedate(new org.joda.time.DateTime());
            consent.setSigndate(new org.joda.time.DateTime());
            
            RevokeHCPartyConsentResponse revokePatientConsentResponse = hubService.revokeHCPartyConsent(consent);
    
            XmlAsserter.assertSimilar(helper.expectedResponse("RevokeHcPartyConsent"), ConnectorXmlUtils.toString(revokePatientConsentResponse));
        }
    
        [Test]
        public void _220_revokeTherapeuticLink() {
            TherapeuticLinkType therapeuticLink = helper.createTherapeuticLinkType();
            therapeuticLink.setEnddate(new org.joda.time.DateTime());
            RevokeTherapeuticLinkResponse revokeTherapeuticLink = hubService.revokeTherapeuticLink(therapeuticLink);
    
            XmlAsserter.assertSimilar(helper.expectedResponse("RevokeTherapeuticLink"), ConnectorXmlUtils.toString(revokeTherapeuticLink));

        }
    
        [Test]
        public void _230_revokePatientConsent() {
            ConsentType consent = helper.createConsentType();
            consent.setRevokedate(new org.joda.time.DateTime());
            RevokePatientConsentResponse revokePatientConsent = hubService.revokePatientConsent(consent);
    
            XmlAsserter.assertSimilar(helper.expectedResponse("RevokePatientConsent"), ConnectorXmlUtils.toString(revokePatientConsent));

        }
        
    
        [Test]
        [Ignore("Not implemented by RSW")]
        public void _240_putAccessRight() {
            AccessRightType accessRight = new AccessRightType();
            CDACCESSRIGHT cdAccessRight = new CDACCESSRIGHT();
            cdAccessRight.setS(CDACCESSRIGHTschemes.CD_ACCESSRIGHT);
            cdAccessRight.setSV("1.0");
            cdAccessRight.setValue(CDACCESSRIGHTvalues.ALLOW);
            accessRight.setCd(cdAccessRight);
            be.fgov.ehealth.hubservices.core.v3.HcpartyType hcParty = new be.fgov.ehealth.hubservices.core.v3.HcpartyType();
            hcParty.getCds().add(helper.createCdHcPartyProfession());
            hcParty.getIds().add(helper.createIdHcPartyNihii());
            accessRight.setHcparty(hcParty);
            TransactionIdType transaction = helper.createTransactionIdType(transactionId);
            accessRight.setTransaction(transaction);
            hubService.putAccessRight(accessRight);
        }
    
        [Test]
        [Ignore("Not implemented by RSW")]
        public void _250_getAccessRight() {
            TransactionIdType transaction = new TransactionIdType();
            IDKMEHR id = helper.createMessageId(HubConfigCommon.MESSAGE_ID);
            transaction.getIds().add(id);
            hubService.getAccessRight(transaction);
        }
    
       [Test]
       [Ignore("Not implemented by RSW")]
        public void _260_revokeAccessRight() {
            SelectRevokeAccessRightType accessRight = new SelectRevokeAccessRightType();
            be.fgov.ehealth.hubservices.core.v3.HcpartyType hcParty = new be.fgov.ehealth.hubservices.core.v3.HcpartyType();
            hcParty.getCds().add(helper.createCdHcPartyProfession());
            hcParty.getIds().add(helper.createIdHcPartyNihii());
            accessRight.setHcparty(hcParty);
            accessRight.setTransaction(helper.createTransactionIdType(transactionId));
            hubService.revokeAccessRight(accessRight);
        }
 
	    private void setLatestMedicationSchemeVersion(GetLatestUpdateResponse latestUpdateResponse) {
	    	java.util.List latestUpdates = latestUpdateResponse.getLatestupdatelist().getLatestupdates();
	    	for (int i = 0; i<latestUpdates.size(); i++) {
				Latestupdate latestupdate = (Latestupdate) latestUpdates.get(i);
                if ("medicationscheme".Equals(latestupdate.getCd().getValue())) {
					latestMedicationSchemeVersion = new Integer(latestupdate.getVersion()).intValue();
                }
            }
        }	    
	    
        
        private string retrieveLocalId(java.util.List idkmehrs) {
           for (int i = 0; i<idkmehrs.size(); i++) {
               IDKMEHR idkmehr = (IDKMEHR) idkmehrs.get(i);
               if (IDKMEHRschemes.LOCAL.equals(idkmehr.getS())) {
                   return idkmehr.getValue();
               }
           }
           return null;
        }
	}
	
}
