/*
 * Copyright (c) eHealth
 */
package be.ehealth.businessconnector.hub.session;

import org.joda.time.DateTime;

import be.ehealth.technicalconnector.config.ConfigFactory;
import be.ehealth.technicalconnector.exception.TechnicalConnectorException;
import be.ehealth.technicalconnector.idgenerator.IdGeneratorFactory;
import be.ehealth.technicalconnector.utils.MarshallerHelper;
import be.ehealth.technicalconnector.utils.SessionUtil;
import be.fgov.ehealth.hubservices.core.v1.ConsentType;
import be.fgov.ehealth.hubservices.core.v1.HCPartyIdType;
import be.fgov.ehealth.hubservices.core.v1.PatientIdType;
import be.fgov.ehealth.hubservices.core.v1.TherapeuticLinkType;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDCONSENT;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDCONSENTschemes;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDCONSENTvalues;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDHCPARTY;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDHCPARTYschemes;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDSTANDARD;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDTHERAPEUTICLINK;
import be.fgov.ehealth.standards.kmehr.cd.v1.CDTHERAPEUTICLINKschemes;
import be.fgov.ehealth.standards.kmehr.id.v1.IDHCPARTY;
import be.fgov.ehealth.standards.kmehr.id.v1.IDHCPARTYschemes;
import be.fgov.ehealth.standards.kmehr.id.v1.IDKMEHR;
import be.fgov.ehealth.standards.kmehr.id.v1.IDKMEHRschemes;
import be.fgov.ehealth.standards.kmehr.id.v1.IDPATIENT;
import be.fgov.ehealth.standards.kmehr.id.v1.IDPATIENTschemes;
import be.fgov.ehealth.standards.kmehr.schema.v1.AuthorType;
import be.fgov.ehealth.standards.kmehr.schema.v1.HcpartyType;
import be.fgov.ehealth.standards.kmehr.schema.v1.HeaderType;
import be.fgov.ehealth.standards.kmehr.schema.v1.PersonType;
import be.fgov.ehealth.standards.kmehr.schema.v1.RecipientType;
import be.fgov.ehealth.standards.kmehr.schema.v1.SenderType;
import be.fgov.ehealth.standards.kmehr.schema.v1.StandardType;
import be.fgov.ehealth.standards.kmehr.schema.v1.TransactionType;

/**
 * @author EH076
 *
 */
public class HubTestHelper {
   

    /**
     * Initialise properties with VZNKUL hub values
     * @throws TechnicalConnectorException 
     */
    static void initHub(String hubid) throws TechnicalConnectorException {
        if (HubConfig.HUBID_RSW.equalsIgnoreCase(hubid)) {
            ConfigFactory.getConfigValidator().getConfig().setProperty(HubConfig.ENDPOINT_HUB_INTRA, HubConfig.URL_RSW);
            AbstractIntrahubIntegrationTest.props.setProperty(HubConfig.HUB_ID, HubConfig.HUBID_RSW);
        } else if (HubConfig.HUBID_VZNKUL.equalsIgnoreCase(hubid)) {
            ConfigFactory.getConfigValidator().getConfig().setProperty(HubConfig.ENDPOINT_HUB_INTRA, HubConfig.URL_VZNKUL);
            AbstractIntrahubIntegrationTest.props.setProperty(HubConfig.HUB_ID, HubConfig.HUBID_VZNKUL);
        } else if (HubConfig.HUBID_COZO.equalsIgnoreCase(hubid)) {
            ConfigFactory.getConfigValidator().getConfig().setProperty(HubConfig.ENDPOINT_HUB_INTRA, HubConfig.URL_COZO);
            AbstractIntrahubIntegrationTest.props.setProperty(HubConfig.HUB_ID, HubConfig.HUBID_COZO);
        } else if (HubConfig.HUBID_ARH.equalsIgnoreCase(hubid)) {
            ConfigFactory.getConfigValidator().getConfig().setProperty(HubConfig.ENDPOINT_HUB_INTRA, HubConfig.URL_ARH);
            AbstractIntrahubIntegrationTest.props.setProperty(HubConfig.HUB_ID, HubConfig.HUBID_ARH);
        }
        AbstractIntrahubIntegrationTest.props.setProperty(HubConfig.HUB_APP, "");
    }

    /**
     * Create an IDPATIENT for Niss
     */
    protected static IDPATIENT createIdPatientInss() {
        IDPATIENT idPatient = new IDPATIENT();
        idPatient.setS(IDPATIENTschemes.INSS);
        idPatient.setSV(HubConfig.SV_ID);
        idPatient.setValue(HubConfig.PATIENT_INSS);
        return idPatient;
    }

    /**
     * Create an IDPATIENT for Niss
     */
    protected static IDPATIENT createIdPatientCardno() {
        IDPATIENT idPatient = new IDPATIENT();
        idPatient.setS(IDPATIENTschemes.EID_CARDNO);
        idPatient.setSV(HubConfig.SV_ID);
        idPatient.setValue(HubConfig.PATIENT_CARDNO);
        return idPatient;
    }

    /**
     * Create an IDHCPARTY for Niss
     */
    protected static IDHCPARTY createIdHcPartyNiss(String value) {
        IDHCPARTY idHcparty = new IDHCPARTY();
        idHcparty.setS(IDHCPARTYschemes.INSS);
        idHcparty.setSV(HubConfig.SV_ID);
        idHcparty.setValue(value);
        return idHcparty;
    }

    /**
     * Create an IDHCPARTY for Nihii
     */
    protected static IDHCPARTY createIdHcPartyNihii() throws TechnicalConnectorException {
        IDHCPARTY idHcparty = new IDHCPARTY();
        idHcparty.setS(IDHCPARTYschemes.ID_HCPARTY);
        idHcparty.setSV(HubConfig.SV_ID);
        idHcparty.setValue(SessionUtil.getNihii11());
        return idHcparty;
    }

    /**
     * Create an IDKMEHR with the specified value
     */
    protected static IDKMEHR createMessageId(String value) throws Exception {
        IDKMEHR id = new IDKMEHR();
        id.setS(IDKMEHRschemes.ID_KMEHR);
        id.setSV(HubConfig.SV_ID);
        id.setValue(value);
        return id;
    }

    /**
     * Create a HcPartyId with the informations of the professional
     */
    protected static HCPartyIdType createHcPartyIdProfessional() throws TechnicalConnectorException {
        HCPartyIdType hcParty = new HCPartyIdType();
        IDHCPARTY idHcparty = createIdHcPartyNihii();
        hcParty.getIds().add(idHcparty);
        idHcparty = createIdHcPartyNiss(HubConfig.PROF_INSS);
        hcParty.getIds().add(idHcparty);
        return hcParty;
    }

    /**
     * Create the professional HcParty
     */
    protected static HcpartyType createHcPartyProfessional() {
        HcpartyType hcParty = new HcpartyType();
        hcParty.setFamilyname(HubConfig.PROF_LASTNAME);
        hcParty.setFirstname(HubConfig.PROF_FIRSTNAME);
        CDHCPARTY cdHcParty = createCdHcPartyProfession();
        hcParty.getCds().add(cdHcParty);
        IDHCPARTY idHcparty = createIdHcPartyNiss(HubConfig.PROF_INSS);
        hcParty.getIds().add(idHcparty);
        return hcParty;
    }

    /**
     * Create a PatientIdType Used by createConsentType
     */
    protected static PatientIdType createPatientIdType() {
        PatientIdType patient = new PatientIdType();
        IDPATIENT idPatient = createIdPatientInss();
        IDPATIENT idPatientCardNo = createIdPatientCardno();
        patient.getIds().add(idPatient);
        patient.getIds().add(idPatientCardNo);
        return patient;
    }

    /**
     * Create a cd with the profession in it Used by createHcPartyProfessional
     */
    protected static CDHCPARTY createCdHcPartyProfession() {
        CDHCPARTY cdHcParty = new CDHCPARTY();
        cdHcParty.setS(CDHCPARTYschemes.CD_HCPARTY);
        cdHcParty.setSV(HubConfig.SV_CD);
        cdHcParty.setValue(HubConfig.PROF_PROFESSION);
        return cdHcParty;
    }

    /**
     * Create the header of the transaction
     */
    protected static HeaderType createHeader() throws Exception {
        HeaderType header = new HeaderType();
    
        StandardType standard = new StandardType();
        CDSTANDARD cd = new CDSTANDARD();
        cd.setSV("1.4");
        cd.setValue("20110701");
        cd.setS("CD-STANDARD");
        standard.setCd(cd);
    
        header.setStandard(standard);
        header.getIds().add(createMessageId(SessionUtil.getNihii11() + "." + IdGeneratorFactory.getIdGenerator().generateId()));
        DateTime now = new DateTime();
        header.setDate(now);
        header.setTime(now);
        header.getRecipients().add(createHub());
        header.setSender(createSender());
        return header;
    }

    /**
     * Create the author of the operation
     */
    protected static SenderType createSender() throws TechnicalConnectorException {
        HcpartyType hcParty = new HcpartyType();
    
        IDHCPARTY doctorNISS = new IDHCPARTY();
        IDHCPARTY doctorNIHII = new IDHCPARTY();
        CDHCPARTY hcPartytype = new CDHCPARTY();
    
        doctorNIHII.setS(IDHCPARTYschemes.ID_HCPARTY);
        doctorNIHII.setSV(HubConfig.SV_ID);
        doctorNIHII.setValue(SessionUtil.getNihii());
    
        doctorNISS.setS(IDHCPARTYschemes.INSS);
        doctorNISS.setSV(HubConfig.SV_ID);
        doctorNISS.setValue(HubConfig.PROF_INSS);
    
        hcPartytype.setS(CDHCPARTYschemes.CD_HCPARTY);
        hcPartytype.setSV(HubConfig.SV_CD);
        hcPartytype.setValue(HubConfig.PROF_PROFESSION);
    
        hcParty.getIds().add(doctorNIHII);
        hcParty.getIds().add(doctorNISS);
        hcParty.getCds().add(hcPartytype);
    
        hcParty.setFamilyname(HubConfig.PROF_LASTNAME);
        hcParty.setFirstname(HubConfig.PROF_FIRSTNAME);
    
        SenderType sender = new SenderType();
        sender.getHcparties().add(hcParty);
    
        return sender;
    }

    /**
     * Create the author of the operation
     */
    protected static AuthorType createAuthor() {
        AuthorType author = new AuthorType();
        HcpartyType hcParty = createHcPartyProfessional();
        author.getHcparties().add(hcParty);
        return author;
    }

    /**
     * Create the Hub of the operation
     */
    protected static RecipientType createHub() {
        HcpartyType hub = new HcpartyType();
    
        IDHCPARTY id = new IDHCPARTY();
        id.setValue(HubConfig.CHOSENHUB_ID);
        id.setS(IDHCPARTYschemes.ID_HCPARTY);
        id.setSV(HubConfig.SV_ID);
        hub.getIds().add(id);
    
        CDHCPARTY cd = new CDHCPARTY();
        cd.setValue("hub");
        cd.setSV(HubConfig.SV_CD);
        cd.setS(CDHCPARTYschemes.CD_HCPARTY);
        hub.getCds().add(cd);
    
        hub.setName(HubConfig.CHOSENHUB_NAME);
        RecipientType rec = new RecipientType();
        rec.getHcparties().add(hub);
        return rec;
    }

    /**
     * Create a consentType used for consent operations
     */
    protected static ConsentType createConsentType() {
        ConsentType consent = new ConsentType();
    
        CDCONSENT cdConsent = new CDCONSENT();
        cdConsent.setS(CDCONSENTschemes.CD_CONSENTTYPE);
        cdConsent.setSV(HubConfig.SV_CD);
        cdConsent.setValue(CDCONSENTvalues.RETROSPECTIVE);
        consent.getCds().add(cdConsent);
    
        consent.setAuthor(createAuthor());
        consent.setPatient(createPatientIdType());
        consent.setSigndate(new DateTime());
    
        return consent;
    }

    /**
     * Create a TherapeuticLinkType used for ther link operations
     */
    protected static TherapeuticLinkType createTherapeuticLinkType() throws TechnicalConnectorException {
        TherapeuticLinkType therapeuticLink = new TherapeuticLinkType();
    
        CDTHERAPEUTICLINK cdTherLink = new CDTHERAPEUTICLINK();
        cdTherLink.setS(CDTHERAPEUTICLINKschemes.CD_THERAPEUTICLINKTYPE);
        cdTherLink.setSV(HubConfig.SV_CD);
        cdTherLink.setValue("gpconsultation");
        therapeuticLink.setCd(cdTherLink);
    
        therapeuticLink.setHcparty(createHcPartyIdProfessional());
        therapeuticLink.setPatient(createPatientIdType());
        therapeuticLink.setStartdate(new DateTime());
        return therapeuticLink;
    }

    /**
     * Create a transaction type needed for transaction operations
     */
    protected static TransactionType createTransactionType() throws Exception {
        MarshallerHelper<TransactionType, TransactionType> helper = new MarshallerHelper<TransactionType, TransactionType>(TransactionType.class, TransactionType.class);
        TransactionType transaction = helper.toObject(
            "<transaction xmlns='http://www.ehealth.fgov.be/standards/kmehr/schema/v1'><id S='ID-KMEHR' SV='1.0'>1</id><cd S='CD-TRANSACTION' SV='1.4'>sumehr</cd><date>2013-07-17</date><time>10:01:51+01:00</time><iscomplete>true</iscomplete><isvalidated>true</isvalidated><item><id S='ID-KMEHR' SV='1.0'>1</id><cd S='CD-ITEM' SV='1.4'>risk</cd><content><text L='fr'>travail sur écran</text></content><beginmoment><date>2013-06-21</date><time>14:51:24+01:00</time></beginmoment><recorddatetime>2013-06-21T14:53:28+02:00</recorddatetime></item><item><id S='ID-KMEHR' SV='1.0'>2</id><cd S='CD-ITEM' SV='1.4'>adr</cd><content><text L='fr'>Ticlopidine</text></content><beginmoment><date>2013-06-21</date><time>14:51:24+01:00</time></beginmoment><recorddatetime>2013-06-21T14:52:34+02:00</recorddatetime></item><item><id S='ID-KMEHR' SV='1.0'>3</id><cd S='CD-ITEM' SV='1.4'>medication</cd><content><cd S='CD-ATC' SV='1.0'>B01AC05</cd></content><content><text L='fr'>Ticlid (c) 250mg - 30 compr. enrobé(s)</text></content><content><medicinalproduct><intendedcd S='CD-DRUG-CNK' SV='2.0'>0857995</intendedcd><intendedname>Ticlid (c) 250mg - 30 compr. enrobé(s)</intendedname></medicinalproduct></content><beginmoment><date>2013-06-21</date></beginmoment><lifecycle><cd S='CD-LIFECYCLE' SV='1.3'>prescribed</cd></lifecycle><isrelevant>true</isrelevant><temporality><cd S='CD-TEMPORALITY' SV='1.0'>chronic</cd></temporality><quantity><decimal>1</decimal><unit><cd S='CD-UNIT' SV='1.3'>pkg</cd></unit></quantity><instructionforpatient L='fr'>1 compr. enrobé(s) 1 x / jour</instructionforpatient><recorddatetime>2013-06-21T14:51:24+02:00</recorddatetime></item><item><id S='ID-KMEHR' SV='1.0'>4</id><cd S='CD-ITEM' SV='1.4'>medication</cd><content><cd S='CD-ATC' SV='1.0'>C10AA07</cd></content><content><text L='fr'>rosuvastatine 40 mg - 98 compr. pelliculé(s)</text></content><content><medicinalproduct><intendedcd S='CD-DRUG-CNK' SV='2.0'>2055176</intendedcd><intendedname>rosuvastatine 40 mg - 98 compr. pelliculé(s)</intendedname></medicinalproduct></content><beginmoment><date>2013-06-21</date></beginmoment><endmoment><date>2013-09-27</date></endmoment><lifecycle><cd S='CD-LIFECYCLE' SV='1.3'>prescribed</cd></lifecycle><isrelevant>true</isrelevant><temporality><cd S='CD-TEMPORALITY' SV='1.0'>acute</cd></temporality><quantity><decimal>1</decimal><unit><cd S='CD-UNIT' SV='1.3'>pkg</cd></unit></quantity><instructionforpatient L='fr'>1 compr. 1 x / jour</instructionforpatient><recorddatetime>2013-06-21T14:51:24+02:00</recorddatetime></item><item><id S='ID-KMEHR' SV='1.0'>5</id><cd S='CD-ITEM' SV='1.4'>vaccine</cd><content><cd S='CD-VACCINEINDICATION' SV='1.0'>diphteria</cd><cd S='CD-VACCINEINDICATION' SV='1.0'>tetanus</cd><cd S='CD-ATC' SV='1.0'>J07AM51</cd></content><content><medicinalproduct><intendedcd S='CD-DRUG-CNK' SV='2.0'>1077593</intendedcd><intendedname>Tedivax pro adulto (c)</intendedname></medicinalproduct></content><beginmoment><date>2013-05-28</date></beginmoment><lifecycle><cd S='CD-LIFECYCLE' SV='1.3'>administrated</cd></lifecycle><recorddatetime>2013-06-21T14:53:34+02:00</recorddatetime></item><item><id S='ID-KMEHR' SV='1.0'>6</id><cd S='CD-ITEM' SV='1.4'>vaccine</cd><content><cd S='CD-VACCINEINDICATION' SV='1.0'>diphteria</cd><cd S='CD-VACCINEINDICATION' SV='1.0'>tetanus</cd><cd S='CD-VACCINEINDICATION' SV='1.0'>pertussis</cd><cd S='CD-VACCINEINDICATION' SV='1.0'>poliomyelitis</cd><cd S='CD-ATC' SV='1.0'>J07CA02</cd></content><content><medicinalproduct><intendedcd S='CD-DRUG-CNK' SV='2.0'>2374429</intendedcd><intendedname>Boostrix Polio (c)</intendedname></medicinalproduct></content><beginmoment><date>2013-05-28</date></beginmoment><lifecycle><cd S='CD-LIFECYCLE' SV='1.3'>administrated</cd></lifecycle><recorddatetime>2013-06-21T14:53:34+02:00</recorddatetime></item></transaction>");
    
        AuthorType author = new AuthorType();
        author.getHcparties().addAll(createSender().getHcparties());
    
        transaction.setAuthor(author);
        transaction.getIds().add(createMessageId(HubConfig.MESSAGE_ID));
        transaction.getIds().add(createTransactionId(AbstractIntrahubIntegrationTest.transactionId));
        return transaction;
    }

    /**
     * Create the transaction id with the specified value
     */
    protected static IDKMEHR createTransactionId(String version) {
        IDKMEHR id = new IDKMEHR();
        id.setS(IDKMEHRschemes.LOCAL);
        id.setSL("EHBASICSOFT");
        id.setSV("3.4.0-beta-5");
        id.setValue(version);
        return id;
    }

    /**
     * Create the patient needed for some transaction
     */
    protected static PersonType createPatientForTransaction() throws Exception {
        PersonType patient = new PersonType();
        IDPATIENT kmehrPatientId = new IDPATIENT();
        kmehrPatientId.setS(IDPATIENTschemes.INSS);
        kmehrPatientId.setSV(HubConfig.SV_ID);
        kmehrPatientId.setValue(HubConfig.PATIENT_INSS);
        patient.getIds().add(kmehrPatientId);
        patient.getFirstnames().add(HubConfig.PATIENT_FIRSTNAME);
        patient.setFamilyname(HubConfig.PATIENT_LASTNAME);
        return patient;
    }

}
