/*
 * Copyright (c) eHealth
 */
using System;
using be.ehealth.business.kmehrcommons;
using be.ehealth.businessconnector.wsconsent.builders;
using be.ehealth.businessconnector.wsconsent.service;
using be.ehealth.businessconnector.wsconsent.session;
using be.ehealth.technicalconnector.session;
using be.ehealth.technicalconnector.utils;
using be.fgov.ehealth.hubservices.core.v2;
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 java.util;
using javax.xml.@namespace;
using NUnit.Framework;
using be.fgov.ehealth.technicalconnector.tests.session;
using be.fgov.ehealth.technicalconnector.tests.utils;

namespace be.ehealth.businessconnector.wsconsent.service
{
	
	public class AbstractWsConsentServiceIntegrationTest
	{
		[SetUp]
		public void init(){
			SessionInitializer.init(".\\be.ehealth.businessconnector.wsconsent.test.properties", SupportedLanguages.NET.getAbbreviation());
		}
		
		
		[TearDown]
	    public static void tearDown() {
	        Session.getInstance().unloadSession();
	    }
		
	    /**
	     * @return
	     * @throws TechnicalConnectorException
	     * @throws WsConsentBusinessConnectorException
	     * @throws InstantiationException
	     * @throws SessionManagementException
	     */
	    public PutPatientConsentResponse putConsentForCurrentPatient(ConsentType consentType) {
	        PutPatientConsentRequest consentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createPutRequest(getAuthor(), consentType);
	        
	        MarshallerHelper marshaller = new MarshallerHelper(consentRequest.getClass(),consentRequest.getClass());
	        String xmlString = marshaller.toString(consentRequest);
	        
	        Console.WriteLine("logging jaxb ojbect : " + xmlString);
	        // Service
	        be.ehealth.businessconnector.wsconsent.service.WsConsentService service = ServiceFactory.getWsConsentService();
	        PutPatientConsentResponse response = service.putPatientConsent(Session.getInstance().getSession().getSAMLToken(), consentRequest);
	        return response;
	    }
	
	
	    /**
	     * @return
	     * @throws TechnicalConnectorException
	     * @throws WsConsentBusinessConnectorException
	     * @throws InstantiationException
	     */
	    public AuthorWithPatientType getAuthor() {
	        AuthorWithPatientType author = RequestObjectBuilderFactory.getAuthorBuilder().createAuthor();
	        return author;
	    }
	
	
	    /**
	     * @return
	     * @throws TechnicalConnectorException
	     */
	    public PatientIdType getPatient() {
	        PatientIdType patient = RequestObjectBuilderFactory.getPatientInfoBuilder().readFromEidCard();
	        return patient;
	    }
	
	
	    /**
	     * @return
	     * @throws TechnicalConnectorException
	     * @throws WsConsentBusinessConnectorException
	     * @throws InstantiationException
	     * @throws SessionManagementException
	     */
	    public GetPatientConsentResponse retrievePatientConsentResponse() {
	        java.util.List consentList = new ArrayList();
	        consentList.add(CDConsentBuilderUtil.createCDConsent("1.0", CDCONSENTvalues.RETROSPECTIVE));
	
	        SelectGetPatientConsentType consentType = RequestObjectBuilderFactory.getConsentBuilder().createSelectGetPatientConsent(getPatient(), consentList);
	        AuthorWithPatientType author = getAuthor();
	
	        GetPatientConsentRequest consentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createGetRequest(author, consentType);
	
			MarshallerHelper marshaller = new MarshallerHelper(consentRequest.getClass(),consentRequest.getClass());
	        String xmlString = marshaller.toString(consentRequest);
	        Console.WriteLine("logging jaxb ojbect : " + xmlString);
	        // Service
	        be.ehealth.businessconnector.wsconsent.service.WsConsentService service = ServiceFactory.getWsConsentService();
	        GetPatientConsentResponse response = service.getPatientConsent(Session.getInstance().getSession().getSAMLToken(), consentRequest);
	
	        marshaller = new MarshallerHelper(response.getClass(),response.getClass());
	        xmlString = marshaller.toString(response);
	        Console.WriteLine("logging jaxb ojbect : " + xmlString);
	        return response;
	    }
	
	
	    /**
	     * @return
	     * @throws TechnicalConnectorException
	     * @throws WsConsentBusinessConnectorException
	     * @throws InstantiationException
	     * @throws SessionManagementException
	     */
	    public RevokePatientConsentResponse revokePatientconsent(ConsentType consentType) {
	
	        consentType.setRevokedate(new org.joda.time.DateTime());
	        AuthorWithPatientType author = getAuthor();
	
	        RevokePatientConsentRequest consentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createRevokeRequest(author, consentType);
	
	        MarshallerHelper marshaller = new MarshallerHelper(consentRequest.getClass(),consentRequest.getClass());
	        String xmlString = marshaller.toString(consentRequest);
	        Console.WriteLine("logging jaxb ojbect : " + xmlString);
	
	        // Service
	        be.ehealth.businessconnector.wsconsent.service.WsConsentService service = ServiceFactory.getWsConsentService();
	        RevokePatientConsentResponse response = service.revokePatientConsent(Session.getInstance().getSession().getSAMLToken(), consentRequest);
	
	        marshaller = new MarshallerHelper(consentRequest.getClass(),consentRequest.getClass());
	        xmlString = marshaller.toString(consentRequest);
	        Console.WriteLine("logging jaxb ojbect : " + xmlString);
	
	        Console.WriteLine("Response: " + response);
	        Console.WriteLine("isComplete =" + response.getAcknowledge().isIscomplete());
	        java.util.List errors = response.getAcknowledge().getErrors();
	        for(int i=1;i<errors.size();i++){
	        	ErrorType error = (ErrorType)errors.get(i);
	            Console.WriteLine("URL : " + error.getUrl() + " errorMessage : " + error.getDescription().getValue());
	        }
	        return response;
	    }
	
	
	    /**
	     * @return
	     * @throws TechnicalConnectorException
	     * @throws WsConsentBusinessConnectorException
	     * @throws InstantiationException
	     */
	    public ConsentType createNewConsentTypeForCurrentPatientAndAuthor() {
	        java.util.List consentList = new ArrayList();
	        consentList.add(CDConsentBuilderUtil.createCDConsent("1.0", CDCONSENTvalues.RETROSPECTIVE));
	        ConsentType consentType = RequestObjectBuilderFactory.getConsentBuilder().createNewConsent(getPatient(), consentList, new org.joda.time.DateTime(), getAuthor());
	        return consentType;
	    }
	
	    /**
	     * @return
	     * @throws InstantiationException
	     * @throws ConnectorException
	     */
	    public PutPatientConsentResponse putConsentForCurrentPatientWithSessionService(ConsentType consentType) {
	        PutPatientConsentRequest consentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createPutRequest(getAuthor(), consentType);
	        
	        MarshallerHelper marshaller = new MarshallerHelper(consentRequest.getClass(),consentRequest.getClass());
	        String xmlString = marshaller.toString(consentRequest);
	        Console.WriteLine("logging jaxb ojbect : " + xmlString);
	        // Service
	        be.ehealth.businessconnector.wsconsent.session.WsConsentService service = WsConsentSessionServiceFactory.getWsConsentService();
	        PutPatientConsentResponse response = service.putPatientConsent(consentRequest);
	        return response;
	    }
	
	
	    /**
	     * @return
	     * @throws InstantiationException
	     * @throws ConnectorException
	     */
	    public GetPatientConsentResponse retrievePatientConsentResponseWithSessionService() {
	        java.util.List consentList = new ArrayList();
	        consentList.add(CDConsentBuilderUtil.createCDConsent("1.0", CDCONSENTvalues.RETROSPECTIVE));
	
	        SelectGetPatientConsentType consentType = RequestObjectBuilderFactory.getConsentBuilder().createSelectGetPatientConsent(getPatient(), consentList);
	        AuthorWithPatientType author = getAuthor();
	
	        GetPatientConsentRequest consentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createGetRequest(author, consentType);
	
	        MarshallerHelper marshaller = new MarshallerHelper(consentRequest.getClass(),consentRequest.getClass());
	        String xmlString = marshaller.toString(consentRequest);
	        Console.WriteLine("logging jaxb ojbect : " + xmlString);
	        // Service
	        be.ehealth.businessconnector.wsconsent.session.WsConsentService service = WsConsentSessionServiceFactory.getWsConsentService();
	        GetPatientConsentResponse response = service.getPatientConsent(consentRequest);
	
	        marshaller = new MarshallerHelper(response.getClass(),response.getClass());
	        xmlString = marshaller.toString(response);
	        Console.WriteLine("logging jaxb ojbect : " + xmlString);
	        return response;
	    }
	
	
	    /**
	     * @return
	     * @throws InstantiationException
	     * @throws ConnectorException
	     */
	    public RevokePatientConsentResponse revokePatientconsentWithSessionService(ConsentType consentType) {
	
	        consentType.setRevokedate(new org.joda.time.DateTime());
	        AuthorWithPatientType author = getAuthor();
	
	        RevokePatientConsentRequest consentRequest = RequestObjectBuilderFactory.getRequestObjectBuilder().createRevokeRequest(author, consentType);
	
	        MarshallerHelper marshaller = new MarshallerHelper(consentRequest.getClass(),consentRequest.getClass());
	        String xmlString = marshaller.toString(consentRequest);
	        Console.WriteLine("logging jaxb ojbect : " + xmlString);
	
	        // Service
	        be.ehealth.businessconnector.wsconsent.session.WsConsentService service = WsConsentSessionServiceFactory.getWsConsentService();
	        RevokePatientConsentResponse response = service.revokePatientConsent(consentRequest);
	
	        marshaller = new MarshallerHelper(response.getClass(),response.getClass());
	        xmlString = marshaller.toString(response);
	        Console.WriteLine("logging jaxb ojbect : " + xmlString);
	
	        Console.WriteLine("Response: " + response);
	        Console.WriteLine("isComplete =" + response.getAcknowledge().isIscomplete());
	        java.util.List errors = response.getAcknowledge().getErrors();
	        for(int i=1;i<errors.size();i++){
	        	ErrorType error = (ErrorType)errors.get(i);
	            Console.WriteLine("URL : " + error.getUrl() + " errorMessage : " + error.getDescription().getValue());
	        }
	        return response;
	    }	
	
	    /**
	     * @param revokePatientconsentResponse
	     */
	    public void checkIfSuccesFull(RevokePatientConsentResponse revokePatientconsentResponse) {
	        Assert.IsNotNull(revokePatientconsentResponse);
	        Assert.IsNotNull(revokePatientconsentResponse.getAcknowledge());
	        Assert.IsTrue(revokePatientconsentResponse.getAcknowledge().isIscomplete());
	        Assert.IsTrue(revokePatientconsentResponse.getAcknowledge().getErrors().size() == 0);
	        Console.WriteLine("checkIfSuccesFull : revokePatientResponse indicates success");
	    }
	
	
	    /**
	     * @param firstConsent
	     * @param consent
	     */
	    public void checkIfEqual(ConsentType expected, ConsentType actual) {
	        // name and firstname will not be returned !! -> this info is discarted in the backend
	        // signDate : truncated to date level + different type in return type
	        stripConsentType(expected);
	        stripConsentType(actual);
	
	        String expectedXml = System.Text.Encoding.UTF8.GetString(ConnectorXmlUtils.toByteArray(expected));
	        String actualXml = System.Text.Encoding.UTF8.GetString(ConnectorXmlUtils.toByteArray(actual));
	
	        TestUtils.assertXmlSimular(expectedXml, actualXml);
	    }
	
	    private void stripConsentType(ConsentType content) {
	        content.getPatient().setFirstname(null);
	        content.getPatient().setFamilyname(null);
	        for(int i=0;i<content.getAuthor().getHcparties().size();i++){
	        	HcpartyType hcparty =(HcpartyType)content.getAuthor().getHcparties().get(i);
	        		
	            java.util.List filteredList = new ArrayList();
	            for(int j=0;j<hcparty.getIds().size();i++){
	            	IDHCPARTY idhcparty= (IDHCPARTY)hcparty.getIds().get(j);
	                if (idhcparty.getS() != IDHCPARTYschemes.INSS) {
	                    filteredList.add(idhcparty);
	                }
	            }
	            hcparty.getIds().clear();
	            hcparty.getIds().addAll(filteredList);
	        }
	    }	
	
	    /**
	     * @param putConsentResponse
	     */
	    public void checkIfSuccessFull(PutPatientConsentResponse putConsentResponse) {
	        Assert.IsNotNull(putConsentResponse);
	        Assert.IsNotNull(putConsentResponse.getAcknowledge());
	        Assert.IsTrue(putConsentResponse.getAcknowledge().isIscomplete());
	        Assert.IsTrue(putConsentResponse.getAcknowledge().getErrors().size() == 0);
	        Console.WriteLine("checkIfSuccessFull : putConsentResponse was successFull");
	    }
	
	
	    /**
	     * @throws InstantiationException
	     * @throws WsConsentBusinessConnectorException
	     * @throws TechnicalConnectorException
	     * @throws SessionManagementException
	     * 
	     */
	    public void cleanConsents() {
	        GetPatientConsentResponse retrievedPatientConsentResponse = retrievePatientConsentResponse();
	        ConsentType consent = retrievedPatientConsentResponse.getConsent();
	        if (consent != null) {
	            Console.WriteLine("cleanConsents : revoking existing consent");
	            revokePatientconsent(consent);
	        }
	    }
	}
}
