

package gov.va.med.cds.testharness.vhim400.builders;


import gov.va.med.cds.clinicaldata.DomainEntryPoint;

import org.dom4j.Document;
import org.dom4j.DocumentFactory;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Random;
import java.util.Set;


public class CommonBuilder
{
    private static final String DEFAULT_PROVIDER_ID_SOURCE_TABLE = "IdSourceTable";
    private static Random random = new Random();
    private static Map<String, DomainEntryPoint> domainEntryPoints = new HashMap<String, DomainEntryPoint>();


    public static void setRandom( Random aRandom )
    {
        random = aRandom;
    }


    public static Element createPharmacyOrderableItem( String elementName, String itemCodeCodePrefix, String dosageFormCodePrefix )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.add( BaseDatatypesBuilder.createHL72CodedElementLite( "itemCode", itemCodeCodePrefix ) );
        element.add( BaseDatatypesBuilder.createHL72CodedElementLite( "dosageFormCode", dosageFormCodePrefix ) );

        return element;
    }


    public static Element createPharmacyDivision( String elementName, String divisionIdCodePrefix, String ncpdpIdCodePrefix )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.add( BaseDatatypesBuilder.createHL72CodedElementLite( "divisionId", divisionIdCodePrefix ) );

        element.add( BaseDatatypesBuilder.createHL72CodedElementLite( "ncpdpId", ncpdpIdCodePrefix ) );

        return element;
    }


    public static Element createPractitionerLite( String elementName, Element hl72PersonName )
    {

        Element element = DocumentHelper.createElement( elementName );
        element.add( BaseDatatypesBuilder.createHL72PersonIdentifier( "identifier" ) );
        element.addElement( "idSourceTable" ).addText( DEFAULT_PROVIDER_ID_SOURCE_TABLE );
        element.add( hl72PersonName );

        return element;

    }


    public static Element createPractitionerLite( String elementName, Element hl72PersonName, Element hl2PersonIdentifier )
    {

        Element element = DocumentHelper.createElement( elementName );
        element.add( hl2PersonIdentifier );
        element.addElement( "idSourceTable" ).addText( DEFAULT_PROVIDER_ID_SOURCE_TABLE );
        element.add( hl72PersonName );

        return element;

    }


    public static Element createPractitionerLite( String elementName, String familyName, String middleName, String prefix, String given,
                    String suffix, String title )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.add( BaseDatatypesBuilder.createHL72PersonIdentifier( "identifier" ) );
        element.addElement( "idSourceTable" ).addText( DEFAULT_PROVIDER_ID_SOURCE_TABLE );
        element.add( BaseDatatypesBuilder.createHL7PersonName( "name", familyName, middleName, prefix, given, suffix, title ) );

        return element;
    }


    public static Element createPractitionerLite( String elementName, String familyName, String middleName, String prefix, String given,
                    String suffix, String title, String identity, String assigningFacility, String assigningAuthority )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.add( BaseDatatypesBuilder.createHL72PersonIdentifier( "identifier", identity, assigningFacility, assigningAuthority ) );
        element.addElement( "idSourceTable" ).addText( DEFAULT_PROVIDER_ID_SOURCE_TABLE );
        element.add( BaseDatatypesBuilder.createHL7PersonName( "name", familyName, middleName, prefix, given, suffix, title ) );

        return element;
    }


    public static Element createPractitionerParticipationLite( String elementName, String comment, Element practitionerLite )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "comment" ).addText( comment );
        element.add( BaseDatatypesBuilder.createPointInTime( "time" ) );
        element.add( practitionerLite );

        return element;

    }


    public static Element createPractitionerParticipationLite( String elementName, String comment, String familyName, String middleName,
                    String prefix, String given, String suffix, String title, String identity, String assigningFacility, String assigningAuthority )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "comment" ).addText( comment );
        element.add( BaseDatatypesBuilder.createPointInTime( "time" ) );
        element.add( createPractitionerLite( "practitioner", familyName, middleName, prefix, given, suffix, title, identity, assigningFacility,
                        assigningAuthority ) );

        return element;
    }


    public static Element createManagedPractitionerParticipationLite( String elementName, Element practitionerLite, Element signatureMode )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.add( practitionerLite );
        element.addElement( "participationType" ).addText( "ParticipationType" );
        element.add( BaseDatatypesBuilder.createPointInTime( "participationDate" ) );
        element.addElement( "signatureBlockName" ).addText( "SignatureBlockName" );
        element.addElement( "signatureBlockTitle" ).addText( "SignatureBlockTitle" );
        element.add( signatureMode );

        return element;
    }


    /*
     <xsd:group name="ClinicalDataPatientChoice">
     <xsd:choice>
     <xsd:element name="vitalSignObservationEvent" type="vitalsigns:VitalSignObservationEvent"/>
     <xsd:element name="intoleranceCondition" type="allergies:IntoleranceCondition"/>
     <xsd:element name="allergyAssessment" type="allergies:AllergyAssessment"/>
     <xsd:element name="outpatientMedicationPromise" type="pharmacy:OutpatientMedicationPromise"/>
     <xsd:element name="labTestPromise" type="lab:LabTestPromise"/>
     </xsd:choice>
     </xsd:group>
     <xsd:complexType name="ClinicalDataPatient">
     <xsd:sequence>
     <xsd:element name="requestedSourceIds" type="basedatatypes:HL72PersonIdentifier" minOccurs="0" maxOccurs="unbounded"/>
     <xsd:element name="resolvedSourceIds" type="basedatatypes:HL72PersonIdentifier" minOccurs="0" maxOccurs="unbounded"/>
     <xsd:group ref="common:ClinicalDataPatientChoice" minOccurs="0" maxOccurs="unbounded"/>
     </xsd:sequence>
     </xsd:complexType>
     */
    public static Element createClinicalDataPatient( String elementName )
    {

        Element element = DocumentHelper.createElement( elementName );
        return element;
    }


    public static Element createClinicalDataPatient( String elementName, Element sourceId )
    {
        Element element = DocumentHelper.createElement( elementName );

        Element requestResolvedIdentifiers = createRequestedResultantResolvedIdentifier( "requestedSourceIds" );
        Element resultantIdentifiers = createRequestedResultantResolvedIdentifier( "resolvedSourceIds" );

        element.add( requestResolvedIdentifiers );
        element.add( resultantIdentifiers );

        return element;
    }


    private static Element createRequestedResultantResolvedIdentifier( String elementName )
    {

        Element element = DocumentHelper.createElement( elementName );

        return element;
    }


    /*
     <xsd:complexType name="PatientLite">
     <xsd:sequence>
     <xsd:element minOccurs="0" name="identifier" type="basedatatypes:HL72PersonIdentifier"/>
     <xsd:element minOccurs="0" name="name" type="basedatatypes:HL72PersonName"/>
     </xsd:sequence>
     </xsd:complexType>
     */
    public static Element createPatientLite( String elementName )
    {
        Document doc = DocumentFactory.getInstance().createDocument();
        Element root = doc.addElement( elementName );

        root.add( BaseDatatypesBuilder.createHL72PersonIdentifier( "identifier" ) );
        root.add( BaseDatatypesBuilder.createHL7PersonName( "name" ) );

        return doc.getRootElement();
    }

    public static Element createPatientIdLite( String elementName )
    {
        Document doc = DocumentFactory.getInstance().createDocument();
        Element root = doc.addElement( elementName );

        root.add( BaseDatatypesBuilder.createHL72PersonIdentifier( "identifier" ) );

        return doc.getRootElement();
    }

    @SuppressWarnings( "unused" )
    private static String getRandValueFromArray( String[] aArray )
    {
        return aArray[random.nextInt( aArray.length )];
    }


    public static Set<DomainEntryPoint> getDomainEntryPoints( String templateId )
    {
        Set<DomainEntryPoint> domainEntryPointSet = new HashSet<DomainEntryPoint>();
        domainEntryPointSet.add( domainEntryPoints.get( templateId ) );
        return domainEntryPointSet;
    }


    public static void setDomaninEntryPointsMap( Map<String, DomainEntryPoint> domainEntryPoints )
    {
        CommonBuilder.domainEntryPoints = domainEntryPoints;
    }
}
