/*
 * Copyright (c) eHealth
 */
using System;
using be.ehealth.businessconnector.therlink.domain.jaxb;
using NUnit.Framework;
using java.util;
using be.ehealth.businessconnector.therlink.util;
using be.ehealth.business.common.domain;
using be.ehealth.businessconnector.therlink.builders;
using be.ehealth.businessconnector.therlink.domain;
using be.ehealth.businessconnector.therlink.domain.responses;
using be.ehealth.businessconnector.therlink.exception;
using be.ehealth.businessconnector.therlink.mappers;
using be.ehealth.businessconnector.therlink.service.impl;
using be.ehealth.businessconnector.therlink.session;
using be.ehealth.technicalconnector.beid;
using be.ehealth.technicalconnector.beid.domain;
using be.ehealth.technicalconnector.config;
using be.ehealth.technicalconnector.exception;
using be.ehealth.technicalconnector.service.sts.security.impl;
using be.fgov.ehealth.technicalconnector.tests.session;
using be.fgov.ehealth.technicalconnector.tests.utils;

namespace be.ehealth.businessconnector.therlink.util
{
    [TestFixture]
    public class TherlinkTestUtils
    {
        private static String BEID_SCOPE = "tests";
        
        private static java.util.Properties props;
        
        private static TherapeuticLinkTypeValues therapeuticLinkTypeValue;
        
        // cached items
        private static be.ehealth.business.common.domain.Patient offlinePatient;
        
        // cached info from eid card
        private static Proof eidSigningProof;
        
        private static be.ehealth.business.common.domain.Patient patientFromEid;
        
        private static ResponseObjectMapper responseObjectMapper;
        
        private static RequestObjectBuilder requestObjectBuilder;
        
        private static RequestObjectMapper requestObjectMapper;
        
        private static CommonObjectBuilder commonBuilder;
        
        private static PatientMapper patientMapper;
        
        private static be.ehealth.businessconnector.therlink.session.TherLinkService therlinkWS;
        
        private static ProofBuilder proofBuilder;
        
        static TherlinkTestUtils() {
            try {
                props = TestPropertiesLoader.getProperties(TestConstants.THERLINK_TEST_PROPERTIES);
                SessionInitializer.init(TestConstants.THERLINK_TEST_PROPERTIES, SupportedLanguages.NET.getAbbreviation());
                therapeuticLinkTypeValue = TherapeuticLinkTypeValues.valueOf(ConfigFactory.getConfigValidator().getProperty("kmehr.single.hcparty.template.careprovider.in.therapeuticlink.cd.cdhcparty.value").ToUpper());
                
                responseObjectMapper = MapperFactory.getResponseObjectMapper();
                requestObjectBuilder = RequestObjectBuilderFactory.getRequestObjectBuilder();
                requestObjectMapper = MapperFactory.getRequestObjectMapper();
                commonBuilder = RequestObjectBuilderFactory.getCommonBuilder();
                proofBuilder = RequestObjectBuilderFactory.getProofBuilder();
            } catch (java.lang.Exception e) {
                Assert.Fail("error setting up test utils : " + e.getMessage());
            }
        }
        
        public static String getReferralTypeToUse() {
            return therapeuticLinkTypeValue.getReferral();
        }

        private static be.ehealth.businessconnector.therlink.session.TherLinkService getTherlinkWs() {
            if (therlinkWS == null) {
                therlinkWS = TherlinkSessionServiceFactory.getTherlinkService();
            }
            return therlinkWS;
        }
        
        public static void revokeReferralsForEidPatient(java.util.List allPossibleReferralParties) {
            for (int i = 0; i < allPossibleReferralParties.size(); i++) {
                HcParty hcParty = (HcParty)allPossibleReferralParties.get(i);
                TherapeuticLink queryLink = new TherapeuticLink.Builder().withHcParty(hcParty).withPatient(getPatientFromEid()).withStatus(be.ehealth.businessconnector.therlink.domain.requests.TherapeuticLinkStatus.ACTIVE).build();
                java.util.List allTherapeuticLinks = getAllTherapeuticLinksWithQueryLink(queryLink, getEidSigningProof());
                revokeAllLinks(allTherapeuticLinks, getEidSigningProof(), getPatientFromEid());
            }
            // revoking needs eid signing with pin code, so only for patient which has eid card in pc
        }

        /**
         * @param queryTherlink
         * @param proof
         * @throws TechnicalConnectorException
         * @throws TherLinkBusinessConnectorException
         * @throws InstantiationException
         * @throws ConnectorException
         */
        private static void revokeAllLinks(java.util.List listOfTherapeuticLinks, Proof proof, be.ehealth.business.common.domain.Patient patient) {
            if (listOfTherapeuticLinks != null) {
                for (int i = 0; i < listOfTherapeuticLinks.size(); i++) {
                    TherapeuticLink retrievedLink = (TherapeuticLink)listOfTherapeuticLinks.get(i);
                    retrievedLink.setPatient(fillTherlinkPatientWithCorrectDataForProof(retrievedLink.getPatient(), patient, proof));
                    be.ehealth.businessconnector.therlink.domain.requests.RevokeTherapeuticLinkRequest revokeTherapeuticLinkRequest = requestObjectBuilder.createRevokeTherapeuticLinkRequest(retrievedLink.getStartDate().toDateTimeAtStartOfDay(), retrievedLink.getEndDate().toDateTimeAtStartOfDay(), retrievedLink.getPatient(), retrievedLink.getHcParty(), retrievedLink.getType(), "revokeAllLinks : therlink to revoke existing link ", proof);
                    be.fgov.ehealth.hubservices.core.v2.RevokeTherapeuticLinkResponse revokeTherapeuticLinkResponse = getTherlinkWs().revokeTherapeuticLink(requestObjectMapper.mapRevokeTherapeuticLinkRequest(revokeTherapeuticLinkRequest));
                    // ignore error messages with 'no therapeutic link found' = NIP.META.TlServiceBean
                    java.util.List errorsToIgnore = new java.util.ArrayList();
                    errorsToIgnore.add("NIP.META.TlServiceBean");
                    validateAcknowledge(null, responseObjectMapper.mapAcknowledge(revokeTherapeuticLinkResponse.getAcknowledge()), errorsToIgnore);
                }
            }
        }
        
        public static be.ehealth.business.common.domain.Patient fillTherlinkPatientWithOfflinePatientDataForProof(Proof proof) {
            return fillTherlinkPatientWithCorrectDataForProof(getOfflinePatient(), getOfflinePatient(), proof);
        }
        
        /**
         * @param retrievedLink
         * @param patient
         * @param templatePatient : optional , if not given the standard offlinePatient will be expected. the operation will fail if another
         *        patient is used as input!!!
         */
        private static be.ehealth.business.common.domain.Patient fillTherlinkPatientWithCorrectDataForProof(be.ehealth.business.common.domain.Patient therlinkPatient, be.ehealth.business.common.domain.Patient templatePatient, Proof proof) {
            if (therlinkPatient == null || therlinkPatient.getInss() == null) {
                throw new java.lang.IllegalArgumentException("the therlink , its patient and the niss number should be filled out!");
            }
            if (templatePatient == null) {
                templatePatient = getOfflinePatient();
            }
            if (templatePatient == null || templatePatient.getInss() == null) {
                throw new java.lang.IllegalArgumentException("the patient to use as template and its niss should be filled out!!");
            }
            if (!templatePatient.getInss().Equals(therlinkPatient.getInss())) {
                throw new java.lang.IllegalArgumentException("templatePatient is not for same niss number!!");
            }
            be.ehealth.business.common.domain.Patient patientToUse = new be.ehealth.business.common.domain.Patient.Builder().withFamilyName(templatePatient.getLastName()).withFirstName(templatePatient.getFirstName()).withInss(templatePatient.getInss()).build();
            
            if (proof.getType().Equals(ProofTypeValues.EIDREADING.getValue())) {
                String cardNumber = templatePatient.getEidCardNumber();
                checkNotNull(cardNumber, ProofTypeValues.EIDREADING);
                patientToUse.setEidCardNumber(cardNumber);
            } else if (proof.getType().Equals(ProofTypeValues.ISIREADING.getValue())) {
                String cardNumber = templatePatient.getIsiCardNumber();
                checkNotNull(cardNumber, ProofTypeValues.ISIREADING);
                patientToUse.setIsiCardNumber(cardNumber);
            } else if (proof.getType().Equals(ProofTypeValues.SISREADING.getValue())) {
                String cardNumber = templatePatient.getSisCardNumber();
                checkNotNull(cardNumber, ProofTypeValues.SISREADING);
                patientToUse.setSisCardNumber(cardNumber);
            } else if (proof.getType().Equals(ProofTypeValues.EIDSIGNING.getValue())) {
                String cardNumber = templatePatient.getEidCardNumber();
                checkNotNull(cardNumber, ProofTypeValues.EIDSIGNING);
                patientToUse.setEidCardNumber(cardNumber);
            } else {
                throw new java.lang.UnsupportedOperationException("fillTherlinkPatientWithCorrectDataForProof : unsupported proofType " + proof.getType());
            }
            return patientToUse;
        }
        
        /**
         * @param eidCardNumber
         * @param eidreading
         */
        private static void checkNotNull(String cardNumber, ProofTypeValues eidreading) {
            if (cardNumber == null) {
                throw new java.lang.IllegalArgumentException(" the template patient used is missing the required cardNumber for Proof " + eidreading.getValue());
            }
        }
        
        public static void revokeNonReferrals(be.ehealth.business.common.domain.Patient patient) {
            Proof proofForEidReading = proofBuilder.createProofForEidReading();
            revokeNonReferrals(patient, proofForEidReading);
        }
        
        /**
         * @param patient
         * @param proof
         * @throws TechnicalConnectorException
         * @throws TherLinkBusinessConnectorException
         * @throws InstantiationException
         * @throws ConnectorException
         */
        public static void revokeNonReferrals(be.ehealth.business.common.domain.Patient patient, Proof proof) {
            TherapeuticLink queryLink = new TherapeuticLink.Builder().withHcParty(ConfigReader.getCareProvider()).withPatient(patient).withStatus(be.ehealth.businessconnector.therlink.domain.requests.TherapeuticLinkStatus.ACTIVE).build();
            java.util.List allTherapeuticLinks = getAllTherapeuticLinksWithQueryLink(queryLink, proof);
            revokeAllLinks(allTherapeuticLinks, proof, patient);
        }
        
        public static java.util.List getAllTherapeuticLinks(HcParty author, be.ehealth.business.common.domain.Patient patient, String type, Proof proof) {
            return getAllTherapeuticLinks(author, patient, null, null, type, proof);
        }
        
        public static java.util.List getAllTherapeuticLinks(HcParty author, be.ehealth.business.common.domain.Patient patient, org.joda.time.DateTime startDate, org.joda.time.DateTime endTime, String type, Proof proof) {
            TherapeuticLink queryLink = new TherapeuticLink.Builder().withHcParty(author).withPatient(patient).withStartDateTime(startDate).withEndDateTime(endTime).withStatus(be.ehealth.businessconnector.therlink.domain.requests.TherapeuticLinkStatus.ALL).withType(type).build();
            return getAllTherapeuticLinksWithQueryLink(queryLink, proof);
        }
        
        /**
         * @param proof
         * @param queryLink
         * @return
         * @throws TechnicalConnectorException
         * @throws TherLinkBusinessConnectorException
         * @throws InstantiationException
         * @throws ConnectorException
         */
        private static java.util.List getAllTherapeuticLinksWithQueryLink(Proof proof, TherapeuticLink queryLink) {
            return getAllTherapeuticLinksWithQueryLink(queryLink, proof);
        }
        
        /**
         * @param proof
         * @param queryLink
         * @return
         * @throws TechnicalConnectorException
         * @throws TherLinkBusinessConnectorException
         * @throws InstantiationException
         * @throws ConnectorException
         */
        private static java.util.List getAllTherapeuticLinksWithQueryLink(TherapeuticLink queryLink, Proof proof) {
            queryLink.setPatient(fillTherlinkPatientWithCorrectDataForProof(queryLink.getPatient(), queryLink.getPatient(), proof));
            be.ehealth.businessconnector.therlink.domain.requests.GetTherapeuticLinkRequest createGetTherapeuticLinkRequest = requestObjectBuilder.createGetTherapeuticLinkRequest(queryLink, proof);
            be.fgov.ehealth.hubservices.core.v2.GetTherapeuticLinkResponse response = getTherlinkWs().getTherapeuticLink(requestObjectMapper.mapGetTherapeuticLinkRequest(createGetTherapeuticLinkRequest));
            GetTherapeuticLinkResponse mappedGetTherapeuticLinkResponse = responseObjectMapper.mapJaxbToGetTherapeuticLinkResponse(response);
            validateAcknowledge(null, mappedGetTherapeuticLinkResponse.getAcknowledge());
            java.util.List listOfTherapeuticLinks = mappedGetTherapeuticLinkResponse.getListOfTherapeuticLinks();
            
            java.util.ArrayList result = new java.util.ArrayList();
            if (listOfTherapeuticLinks != null) {
                result.addAll(listOfTherapeuticLinks);
            }
            return result;
        }
        
        public static be.ehealth.business.common.domain.Patient getOfflinePatient() {
            if (offlinePatient == null) {
                offlinePatient = new be.ehealth.business.common.domain.Patient.Builder().withSis(props.getProperty(TestConstants.PROP_PATIENT_OFFL_SIS)).withEid(props.getProperty(TestConstants.PROP_PATIENT_OFFL_EID)).withFamilyName(props.getProperty(TestConstants.PROP_PATIENT_OFFL_LASTN)).withFirstName(props.getProperty(TestConstants.PROP_PATIENT_OFFL_FIRSTN)).withInss(props.getProperty(TestConstants.PROP_PATIENT_OFFL_NISS)).build();
            }
            return offlinePatient;
        }
        
        public static void logTherapeuticLinks(java.util.List links) {
            for (int i = 0; i < links.size(); i++) {
                TherapeuticLink therapeuticLink = (TherapeuticLink)links.get(i);
                if (therapeuticLink != null) {
                    System.Console.WriteLine(" therapeuticLink:" + therapeuticLink);
                    
                }
            }
        }
        
        private static System.Object lockThis = new System.Object();
        public static Proof getEidSigningProof()  {
            if (eidSigningProof == null) {
                lock (lockThis) {
                    if (eidSigningProof == null) {
                        eidSigningProof = RequestObjectBuilderFactory.getProofBuilder().createProofForEidSigning(BeIDCredential.getInstance(BEID_SCOPE, "Signature"));
                    }
                }
            }
            return eidSigningProof;
        }
        
        public static be.ehealth.business.common.domain.Patient getPatientFromEid() {
            if (patientFromEid == null) {
                Identity identity = BeIDInfo.getInstance(BEID_SCOPE).getIdentity();
                return new be.ehealth.business.common.domain.Patient.Builder().withEid(identity.getCardNumber()).withFamilyName(identity.getName()).withFirstName(identity.getFirstName()).withMiddleName(identity.getMiddleName()).withInss(identity.getNationalNumber()).build();
            }
            return patientFromEid;
        }
        
        public static HcParty getReferralHcPartyForTherlinkType(TherapeuticLinkTypeValues therlinkType) {
            if (TherapeuticLinkTypeValues.PERSNURSE.Equals(therapeuticLinkTypeValue)) {
                return new HcParty.Builder().withType("persnurse").withInss(props.getProperty(TestConstants.PROP_REFERRAL_NURSE_NISS)).build();
            }
            if (TherapeuticLinkTypeValues.PERSPHARMACIST.Equals(therapeuticLinkTypeValue)) {
                return new HcParty.Builder().withType("perspharmacist").withInss(props.getProperty(TestConstants.PROP_REFERRAL_PHARMACIST_NISS)).build();
            }
            if (TherapeuticLinkTypeValues.PERSPHYSICIAN.Equals(therapeuticLinkTypeValue)) {
                return new HcParty.Builder().withType("persphysician").withInss(props.getProperty(TestConstants.PROP_REFERRAL_DOCTOR_NISS)).build();
            }
            throw new java.lang.IllegalArgumentException("getReferralHcPartyForTherlinkType is not configured yet for type " + therapeuticLinkTypeValue);
            
        }
        
        public static java.util.List getReferralsToTest() {
            java.util.List referralsToTest = new java.util.ArrayList();
            if (TherapeuticLinkTypeValues.PERSNURSE.Equals(therapeuticLinkTypeValue)) {
                referralsToTest.add(getReferralHcPartyForTherlinkType(TherapeuticLinkTypeValues.PERSNURSE));
                return referralsToTest;
            } else if (TherapeuticLinkTypeValues.PERSPHARMACIST.Equals(therapeuticLinkTypeValue)) {
                referralsToTest.add(getReferralHcPartyForTherlinkType(TherapeuticLinkTypeValues.PERSPHARMACIST));
                return referralsToTest;
            } else if (TherapeuticLinkTypeValues.PERSPHYSICIAN.Equals(therapeuticLinkTypeValue)) {
                referralsToTest.add(getReferralHcPartyForTherlinkType(TherapeuticLinkTypeValues.PERSPHYSICIAN));
                referralsToTest.add(getReferralHcPartyForTherlinkType(TherapeuticLinkTypeValues.PERSNURSE));
                referralsToTest.add(getReferralHcPartyForTherlinkType(TherapeuticLinkTypeValues.PERSPHARMACIST));
                
                return referralsToTest;
            }
            throw new java.lang.IllegalArgumentException("choosReferralNissNumberBasedOnCurrentProfessionalType : therapeuticLinkTypeValue " + therapeuticLinkTypeValue + " not configured yet !!!");
        }
        
        
        public static String choosReferralNissNumberBasedOnCurrentProfessionalType() {
            if (TherapeuticLinkTypeValues.PERSPHARMACIST.Equals(therapeuticLinkTypeValue)) {
                return props.getProperty(TestConstants.PROP_REFERRAL_PHARMACIST_NISS);
            } else if (TherapeuticLinkTypeValues.PERSNURSE.Equals(therapeuticLinkTypeValue)) {
                return props.getProperty(TestConstants.PROP_REFERRAL_NURSE_NISS);
            } else if (TherapeuticLinkTypeValues.PERSPHYSICIAN.Equals(therapeuticLinkTypeValue)) {
                return props.getProperty(TestConstants.PROP_REFERRAL_DOCTOR_NISS);
            }
            throw new java.lang.IllegalArgumentException("choosReferralNissNumberBasedOnCurrentProfessionalType : therapeuticLinkTypeValue " + therapeuticLinkTypeValue + " not configured yet !!!");
        }
        
        public static TherapeuticLinkTypeValues getTherapeuticLinkTypeValue() {
            return therapeuticLinkTypeValue;
        }
        
        /**
         * Is the link well created?
         * 
         */
        public static bool doesLinkExist(TherapeuticLink therlink) {
            try {
                System.Threading.Thread.Sleep(1500);
            } catch (System.Threading.ThreadInterruptedException  e) {
                Console.WriteLine("thread interupted " + e.Message);
            }
            if (therlink == null) {
                throw new java.lang.IllegalArgumentException("checkLinkIsCreated received invalid therlink object " + therlink);
            }
            java.util.List allTherapeuticLinks = getAllTherapeuticLinksWithQueryLink(therlink, proofBuilder.createProofForEidReading());
            Assert.IsNotNull(allTherapeuticLinks);
            return (allTherapeuticLinks.size() == 1);
        }
        
        /**
         * Is the link well revoked?
         * 
         */
        protected void checkLinkRevoked(TherapeuticLink link) {
            be.ehealth.businessconnector.therlink.domain.requests.GetTherapeuticLinkRequest createGetTherapeuticLinkRequest = requestObjectBuilder.createGetTherapeuticLinkRequest(link, (Proof[]) null);
            
            be.fgov.ehealth.hubservices.core.v2.GetTherapeuticLinkRequest mapGetTherapeuticLinkRequest = requestObjectMapper.mapGetTherapeuticLinkRequest(createGetTherapeuticLinkRequest);
            GetTherapeuticLinkResponse getResponse = responseObjectMapper.mapJaxbToGetTherapeuticLinkResponse(getTherlinkWs().getTherapeuticLink(mapGetTherapeuticLinkRequest));
            
            if (getResponse.getAcknowledge().isComplete()) {
                if (getResponse.getListOfTherapeuticLinks().size() > 0) {
                    Assert.Fail("Revoke didn't work");
                } else {
                    Console.WriteLine("List size : " + getResponse.getListOfTherapeuticLinks().size());
                }
            } else {
                extractAndAssertErrorMessage(getResponse.getAcknowledge(), null, new java.util.ArrayList());
            }
        }
        
        /**
         * @param expectedErrorCode
         * @param proof
         * @param patient
         * @param hcParty
         * @return
         * @throws TechnicalConnectorException
         * @throws TherLinkBusinessConnectorException
         * @throws InstantiationException
         */
        public static PutTherapeuticLinkResponse putTherapeuticLinkNonReferral(be.ehealth.business.common.domain.Patient patient, HcParty hcParty, org.joda.time.DateTime endDate, Proof proof, String expectedErrorCode) {
            be.ehealth.business.common.domain.Patient patientToUse = chooseOfflinePatientIfPossible(patient, proof);
            be.ehealth.businessconnector.therlink.domain.requests.PutTherapeuticLinkRequest createPutTherapeuticLinkRequest = requestObjectBuilder.createPutTherapeuticLinkRequest(endDate, patientToUse, hcParty, therapeuticLinkTypeValue.getTherlinkType(), "therlink test", proof);
            be.fgov.ehealth.hubservices.core.v2.PutTherapeuticLinkRequest mapPutTherapeuticLinkRequest = requestObjectMapper.mapPutTherapeuticLinkRequest(createPutTherapeuticLinkRequest);
            PutTherapeuticLinkResponse putResponse = responseObjectMapper.mapJaxbToPutTherapeuticLinkResponse(getTherlinkWs().putTherapeuticLink(mapPutTherapeuticLinkRequest));
            
            validateResponse(expectedErrorCode, putResponse);
            return putResponse;
        }
        
        /**
         * @param patient
         * @param proof
         * @return
         */
        private static be.ehealth.business.common.domain.Patient chooseOfflinePatientIfPossible(be.ehealth.business.common.domain.Patient patient, Proof proof) {
            be.ehealth.business.common.domain.Patient offlinePatientWithCorrectProperties = fillTherlinkPatientWithOfflinePatientDataForProof(proof);
            if (patient != null) {
                if (!offlinePatientWithCorrectProperties.getInss().Equals(patient.getInss())) {
                    return patient;
                }
            }
            return offlinePatientWithCorrectProperties;
        }
        
        /**
         * @param expectedErrorCode
         * @param putResponse
         */
        public static void validateResponse(String expectedErrorCode, PutTherapeuticLinkResponse putResponse) {
            Acknowledge acknowledge = putResponse.getAcknowledge();
            validateAcknowledge(expectedErrorCode, acknowledge);
        }
        
        /**
         * @param expectedErrorCode
         * @param acknowledge
         */
        private static void validateAcknowledge(String expectedErrorCode, Acknowledge acknowledge) {
            validateAcknowledge(expectedErrorCode, acknowledge, null);
        }
        
        /**
         * @param expectedErrorCode
         * @param acknowledge
         */
        private static void validateAcknowledge(String expectedErrorCode, Acknowledge acknowledge, java.util.List errorsToIgnore) {
            if (acknowledge.isComplete()) {
                Console.WriteLine(">>> Therapeutic link created");
                if (expectedErrorCode != null) {
                    Assert.Fail("expected error with code " + expectedErrorCode + ", but no errors returned");
                }
            } else {
                extractAndAssertErrorMessage(acknowledge, expectedErrorCode, errorsToIgnore);
            }
        }
        
        /**
         * Gets all the existing links between the current patient and the given hcParty, and revoke them all
         * 
         * Used to initialise this test
         */
        protected static void revokeLinksInit(HcParty hcp)  {
            // Retrieve all the links
            be.ehealth.business.common.domain.Patient patient = TherlinkTestUtils.getPatientFromEid();
            TherapeuticLink createTherapeuticLink = commonBuilder.createTherapeuticLink(null, null, patient, requestObjectBuilder.getEnduserHcpType(), null, null, hcp);
            be.ehealth.businessconnector.therlink.domain.requests.GetTherapeuticLinkRequest createDefaultGetTherapeuticLinkRequest = new be.ehealth.businessconnector.therlink.domain.requests.GetTherapeuticLinkRequest(commonBuilder.createKmehrID(), new Date(), commonBuilder.createAuthor(requestObjectBuilder.getAuthorHcParties()), createTherapeuticLink, requestObjectBuilder.getMaxRows(), TherlinkTestUtils.getEidSigningProof());
            
            be.fgov.ehealth.hubservices.core.v2.GetTherapeuticLinkRequest mapGetTherapeuticLinkRequest = requestObjectMapper.mapGetTherapeuticLinkRequest(createDefaultGetTherapeuticLinkRequest);
            be.fgov.ehealth.hubservices.core.v2.GetTherapeuticLinkResponse therapeuticLinkresponse = getTherlinkWs().getTherapeuticLink(mapGetTherapeuticLinkRequest);
            GetTherapeuticLinkResponse resp = responseObjectMapper.mapJaxbToGetTherapeuticLinkResponse(therapeuticLinkresponse);
            
            if (!resp.getAcknowledge().isComplete()) {
                // if the therapeutic link did not exist (=TL.ACCESS.09) , let it go
                extractAndAssertErrorMessage(resp.getAcknowledge(), "TL.ACCESS.09", new java.util.ArrayList());
            }
            
            if (resp.getListOfTherapeuticLinks() != null && resp.getListOfTherapeuticLinks().size() > 0) {
                // Revoke existing links
                Console.WriteLine(">>> Revoke existing therapeutic links");
                for (int i = 0; i < resp.getListOfTherapeuticLinks().size(); i++) {
                    TherapeuticLink therLink = (TherapeuticLink) resp.getListOfTherapeuticLinks().get(i);
                    Console.WriteLine(">>> " + therLink.toString());
                    be.ehealth.business.common.domain.Patient patientFromTherapeuticLink = therLink.getPatient();
                    // add eidcard number to retrieved therapeutic link, so revoke with eidReading is possible
                    if (patientFromTherapeuticLink.getInss().Equals(patient.getInss())) {
                        patientFromTherapeuticLink.setEidCardNumber(patient.getEidCardNumber());
                    }
                    be.ehealth.businessconnector.therlink.domain.requests.RevokeTherapeuticLinkRequest createRevokeTherapeuticLinkRequest = requestObjectBuilder.createRevokeTherapeuticLinkRequestWithProof(therLink, TherlinkTestUtils.getEidSigningProof());
                    
                    be.fgov.ehealth.hubservices.core.v2.RevokeTherapeuticLinkRequest mapRevokeTherapeuticLinkRequest = requestObjectMapper.mapRevokeTherapeuticLinkRequest(createRevokeTherapeuticLinkRequest);
                    
                    RevokeTherapeuticLinkResponse response = responseObjectMapper.mapJaxbToRevokeTherapeuticLinkResponse(getTherlinkWs().revokeTherapeuticLink(mapRevokeTherapeuticLinkRequest));
                    
                    if (response.getAcknowledge().isComplete()) {
                        Console.WriteLine(">>> Link revoked");
                    } else {
                        extractAndAssertErrorMessage(response.getAcknowledge(), null, new java.util.ArrayList());
                    }
                }
            } else {
                Console.WriteLine(">>> No existing therapeutic link");
            }
            
        }
        
        /**
         * Extracts error messages from an acknowledge
         */
        protected static void extractErrorMessage(Acknowledge response) {
            extractAndAssertErrorMessage(response, null, new java.util.ArrayList());
        }
        
        /**
         * Extracts error messages from an acknowledge
         */
        protected static void extractErrorMessage(Acknowledge response, String expectedErrorCode) {
            extractAndAssertErrorMessage(response, expectedErrorCode, new java.util.ArrayList());
        }
        
        public static void logErrorMessages(Acknowledge acknowledge) {
            java.lang.StringBuilder sb = new java.lang.StringBuilder("acknowledge received : " + acknowledge.getListOfErrors().size() + " errors:");
            for (int i = 0; i < acknowledge.getListOfErrors().size(); i++) {
                TherapeuticLinkResponseError error = (TherapeuticLinkResponseError)acknowledge.getListOfErrors().get(i);
                sb.append("\n   >>> Error code: " + error.getErrorCode());
                sb.append("   >>> Error description : " + error.getErrorDescription());
            }
            Console.WriteLine(sb.toString());
        }
        
        /**
         * Extracts error messages from an acknowledge
         */
        public static void extractAndAssertErrorMessage(Acknowledge response, String expectedErrorCode) {
            extractAndAssertErrorMessage(response, expectedErrorCode, new java.util.ArrayList());
        }
        
        /**
         * Extracts error messages from an acknowledge
         */
        public static void extractAndAssertErrorMessage(Acknowledge response, String expectedErrorCode, java.util.List errorsToIgnore) {
            java.lang.StringBuilder errorList = new java.lang.StringBuilder("List of Errors: ");
            
            bool errorCodeFound = false;
            for (int i =0; i < response.getListOfErrors().size(); i++) {
                TherapeuticLinkResponseError error = (TherapeuticLinkResponseError) response.getListOfErrors().get(i);
                if (expectedErrorCode != null && expectedErrorCode.Equals(error.getErrorCode())) {
                    errorCodeFound = true;
                    errorList.append("\n   >>>  expected Error code: ");
                } else {
                    errorList.append("\n   >>> Error code: ");
                }
                errorList.append(error.getErrorCode());
                errorList.append("   >>> Error description : " + error.getErrorDescription());
            }
            bool ignoreErrors = areErrorsToBeIgnored(response.getListOfErrors(), errorsToIgnore);
            if (expectedErrorCode == null) {
                if (!ignoreErrors) {
                    Assert.Fail(">>> An error occured : " + errorList.toString());
                }
            } else {
                Assert.True(errorCodeFound, "there were errors , but none with errorCode " + expectedErrorCode + " errors found : " + errorList.toString());
            }
        }
        
        /**
         * @param listOfErrors
         * @param errorsToIgnore
         * @return
         */
        private static bool areErrorsToBeIgnored(java.util.List listOfErrors, java.util.List errorsToIgnore) {
            if (errorsToIgnore == null) {
                return listOfErrors.isEmpty();
            }
            for (int i = 0; i < listOfErrors.size(); i++) {
                TherapeuticLinkResponseError responseError = (TherapeuticLinkResponseError) listOfErrors.get(i);
                bool ignoreError = false;
                for (int j = 0; j < errorsToIgnore.size(); j++) {
                    String errorString = (String) errorsToIgnore.get(j);
                    if (errorString != null && errorString.Equals(responseError.getErrorCode())) {
                        ignoreError = true;
                        break;
                    }
                }
                if (!ignoreError) {
                    return false;
                }
            }
            return true;
        }
        
    }
}
