

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


import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;


public class BaseDatatypesBuilder
{
    private static final long DEFAULT_ID = 100000;
    private static final String DEFAULT_IDENTITY = "DefaultIdentiy";
    private static final String DEFAULT_ASSIGNING_FACILITY = "992";
    private static final String DEFAULT_ASSIGNING_AUTHORITY = "USVHA";
    private static final String ISO_FORMAT = "yyyyMMddHHmmssZ";
    private static final String ISO_FORMAT_MS = "yyyyMMddHHmmssSSSZ";
    private static final String[] DEFAULT_PERSON_IDS = { "test_10001", "test_10002", "test_10003", "test_10004", "test_10005" };
    private static final String[] DEFAULT_CODES = { "test_code_2001", "test_code_2002", "test_code_2003", "test_code_2004", "test_code_2005" };
    private static final String[] DEFAULT_ALT_CODES = { "test_altcode_3001", "test_altcode_3002", "test_altcode_3003", "test_altcode_3004", "test_altcode_3005" };
    private static Random random = new Random();


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


    public static Element createHL72CodedElementLite( String elementName, String codePrefix )
    {
        String codeValue = trimString( getRandValueFromArray( DEFAULT_CODES ), 30 );
        return createHL72CodedElementLite( elementName, codePrefix, codeValue );
    }


    public static Element createHL72CodedElementLite( String elementName, String codePrefix, String codeValue )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.addElement( "code" ).addText( trimString( codeValue, 30 ) );
        element.addElement( "displayText" ).addText( codePrefix + "DisplayTextLite" );
        element.addElement( "codingSystem" ).addText( trimString( codePrefix + "CodingSystemLite", 50 ) );
        return element;
    }


    public static Element createHL72CodedElementLite( String elementName, Element hl72CodedElementLite )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.addElement( "code" ).addText( trimString( hl72CodedElementLite.element( "code" ).getText(), 30 ) );
        element.addElement( "displayText" ).addText( hl72CodedElementLite.element( "displayText" ).getText() );
        element.addElement( "codingSystem" ).addText( trimString( hl72CodedElementLite.element( "codingSystem" ).getText(), 50 ) );

        return element;
    }


    public static Element createHL72CodedElement( String elementName, String codePrefix )
    {
        return createHL72CodedElement( elementName, codePrefix, getRandValueFromArray( DEFAULT_CODES ) );
    }


    public static Element createHL72CodedElement( String elementName, String codePrefix, String codeValue )
    {
        Element codedElement = createHL72CodedElementLite( elementName, codePrefix, codeValue );
        codedElement.addElement( "alternateCode" ).addText( trimString( codePrefix + getRandValueFromArray( DEFAULT_ALT_CODES ), 30 ) );
        codedElement.addElement( "alternateDisplayText" ).addText( codePrefix + "AltDisplayTextLite" );
        codedElement.addElement( "alternateCodingSystem" ).addText( trimString( codePrefix + "AltCodingSystem", 50 ) );
        return codedElement;
    }


    public static Element createHL72CodedElementExtended( String elementName, String codePrefix )
    {
        return createHL72CodedElementExtended( elementName, codePrefix, getRandValueFromArray( DEFAULT_CODES ) );
    }


    public static Element createHL72CodedElementExtended( String elementName, String codePrefix, String codeValue )
    {
        Element codedElementExtended = createHL72CodedElement( elementName, codePrefix, codeValue );
        codedElementExtended.addElement( "alternateCodingSystemVersion" ).addText( trimString( codePrefix + getRandValueFromArray( DEFAULT_ALT_CODES ), 30 ) );
        codedElementExtended.addElement( "originalText" ).addText( "OriginalText" );
        return codedElementExtended;
    }


    public static Element createHL72PersonIdentifier( String elementName )
    {
        String entityId = getRandValueFromArray( DEFAULT_PERSON_IDS );
        return createHL72PersonIdentifier( elementName, entityId );
    }


    public static Element createHL72PersonIdentifier( String elementName, String identity )
    {
        return createHL72PersonIdentifier( elementName, identity, DEFAULT_ASSIGNING_FACILITY, DEFAULT_ASSIGNING_AUTHORITY );
    }


    public static Element createHL72PersonIdentifier( String elementName, Element hl72PersonIdentifier )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.add( hl72PersonIdentifier );

        return element;
    }


    public static Element createHL72PersonIdentifier( String elementName, String identity, String assigningFacility )
    {
        return createHL72PersonIdentifier( elementName, identity, assigningFacility, DEFAULT_ASSIGNING_AUTHORITY );
    }


    public static Element createHL72PersonIdentifier( String elementName, String identity, String assigningFacility, String assigningAuthority )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "identity" ).addText( identity );
        element.addElement( "assigningFacility" ).addText( assigningFacility );
        element.addElement( "assigningAuthority" ).addText( assigningAuthority );
        return element;
    }


    public static Element createHL72EntityIdentifier( String elementName, String identity, String namespaceId, String universalId )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.addElement( "identity" ).addText( identity );
        element.addElement( "namespaceId" ).addText( namespaceId );
        element.addElement( "universalId" ).addText( universalId );
        element.addElement( "universalIdType" ).addText( "universalIdType" );

        return element;
    }


    public static Element createHL72EntityIdentifier( String elementName, String identity )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.addElement( "identity" ).addText( identity );
        return element;
    }


    public static Element createHL72EntityIdentifier( String elementName, String identity, String namespaceId, String universalId, String universalIdType )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.addElement( "identity" ).addText( identity );
        if(namespaceId !=null){
            element.addElement( "namespaceId" ).addText( namespaceId );
        }
        if(universalId !=null){
            element.addElement( "universalId" ).addText( universalId );
        }
        if(universalIdType !=null){
            element.addElement( "universalIdType" ).addText( universalIdType );
        }

        return element;
    }


    public static Element createHL72EntityIdentifier( String elementName, String identity, String namespaceId )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.addElement( "identity" ).addText( identity );
        element.addElement( "namespaceId" ).addText( namespaceId );

        return element;
    }


    public static Element createHL72EntityIdentifier( String elementName )
    {
        String suffixString = "" + System.currentTimeMillis();
        String identity = "ID_" + suffixString;
        String universalId = "UID_" + suffixString;

        return createHL72EntityIdentifier( elementName, identity, DEFAULT_ASSIGNING_FACILITY, universalId );
    }


    public static Element createHL72EntityIdentifier( String elementName, long aIdSuffix )
    {
        String suffixString = System.currentTimeMillis() + Long.toString( aIdSuffix );
        String identity = "ID_" + suffixString;
        String universalId = "UID_" + suffixString;

        return createHL72EntityIdentifier( elementName, identity, DEFAULT_ASSIGNING_FACILITY, universalId );
    }


    public static Element createFixedHL72EntityIdentifier( String elementName, long id )
    {
        java.util.Date date = new Date( 0l );
        String element = date.getTime() + Long.toString( id );
        return createHL72EntityIdentifier( elementName, DEFAULT_IDENTITY, DEFAULT_ASSIGNING_FACILITY, element );
    }


    public static Element createHL72FacilityIdentifier( String elementName )
    {
        return createHL72FacilityIdentifier( elementName, DEFAULT_ID );
    }


    public static Element createHL72FacilityIdentifier( String elementName, String namespaceId, String universalId )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.addElement( "namespaceId" ).addText( namespaceId );
        element.addElement( "universalId" ).addText( universalId );
        element.addElement( "universalIdType" ).addText( "universalIdType" );
        return element;
    }


    public static Element createHL72FacilityIdentifier( String elementName, String identity )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.addElement( "identity" ).addText( identity );
        element.addElement( "namespaceId" ).addText( "namespaceId" );
        element.addElement( "universalId" ).addText( "recordIdentifier" );
        element.addElement( "universalIdType" ).addText( "universalIdType" );
        return element;
    }


    public static Element createHL72FacilityIdentifier( String elementName, long id )
    {
        java.util.Date date = new Date();
        String element = date.getTime() + Long.toString( id );
        return createHL72FacilityIdentifier( elementName, DEFAULT_ASSIGNING_FACILITY, element );
    }


    public static Element createFixedHL72FacilityIdentifier( String elementName, long id )
    {
        java.util.Date date = new Date( 0l );
        String element = date.getTime() + Long.toString( id );
        return createHL72FacilityIdentifier( elementName, DEFAULT_ASSIGNING_FACILITY, element );
    }


    public static Element createPointInTime( String elementName )
    {
        Date date = new Date();

        return createPointInTime( elementName, date );
    }

    public static Element createPointInTime( String elementName, java.util.Date date )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "literal" ).addText( formatToISOTime( date ) );

        return element;
    }

    public static Element createPointInTimeMS( String elementName, java.util.Date date )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "literal" ).addText( formatToISOTimeMS( date ) );

        return element;
    }


    public static Element createPointInTime( String elementName, String xsdDateString )
    {
        Element element = DocumentHelper.createElement( elementName );
        element.addElement( "literal" ).addText( xsdDateString );
        return element;
    }


    public static Element createFixedPointInTime( String elementName )
    {
        Element element = DocumentHelper.createElement( elementName );

        Date date = new Date( 0l );
        element.addElement( "literal" ).addText( formatToISOTime( date ) );

        return element;
    }


    public static Element createHL7PersonName( String elementName )
    {
        return createHL7PersonName( elementName, "FamilyName", "MiddleName", "Prefix", "Given", "Suffix", "Title" );
    }


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

        element.addElement( "prefix" ).addText( prefix );
        element.addElement( "given" ).addText( given );
        element.addElement( "middle" ).addText( middleName );
        element.addElement( "family" ).addText( familyName );
        element.addElement( "suffix" ).addText( suffix );
        element.addElement( "title" ).addText( title );

        return element;
    }


    public static String getCurrentISOTime( )
    {
        return new SimpleDateFormat( ISO_FORMAT ).format( new Date() );
    } // End - getISOTime


    public static String formatToISOTime( Date aDate )
    {
        return new SimpleDateFormat( ISO_FORMAT ).format( aDate );
    } // End - getISOTime

    public static String formatToISOTimeMS( Date aDate )
    {
        return new SimpleDateFormat( ISO_FORMAT_MS ).format( aDate );
    } // End - getISOTime

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


    public static Element createHL72OrganizationIdentifier( String elementName, String assigningAuthNamespaceId, String organizationId, String organizationName )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "identity" ).addText( organizationId );
        element.addElement( "name" ).addText( organizationName );
        element.addElement( "assigningAuthority" ).addText( assigningAuthNamespaceId );

        return element;
    }


    public static Element createHL72OrganizationIdentifierExtended( String elementName, String assigningAuthNamespaceId, String organizationId, String organizationName )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "identity" ).addText( organizationId );
        element.addElement( "name" ).addText( organizationName );
        element.addElement( "assigningAuthority" ).addText( assigningAuthNamespaceId );
        element.addElement( "nameTypeCode" ).addText( "NameTypeCode" );
        element.addElement( "identityTypeCode" ).addText( "IdentityTypeCode" );
        element.addElement( "nameRepresentation" ).addText( "NameRepresentation" );
        element.addElement( "stationNumber" ).addText( "StationNumber" );

        return element;
    }


    public static Element createHL72LocationIdentifier( String elementName )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "pointOfCare" ).addText( "PointOfCare" );
        element.addElement( "room" ).addText( "Room" );
        element.addElement( "bed" ).addText( "Bed" );
        element.addElement( "facilityNamespaceId" ).addText( "FacilityNamespaceId" );
        element.addElement( "facilityUniversalId" ).addText( "FacilityUniversalId" );
        element.addElement( "facilityUniversalIdType" ).addText( "FacilityUniversalIdType" );
        element.addElement( "personLocationType" ).addText( "PersonLocationType" );
        element.addElement( "locationDescription" ).addText( "LocationDescription" );

        return element;
    }


    public static Element createHL72LocationIdentifier( String elementName, String locationDescription )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "pointOfCare" ).addText( "PointOfCare" );
        element.addElement( "room" ).addText( "Room" );
        element.addElement( "bed" ).addText( "Bed" );
        element.addElement( "facilityNamespaceId" ).addText( "FacilityNamespaceId" );
        element.addElement( "facilityUniversalId" ).addText( "FacilityUniversalId" );
        element.addElement( "facilityUniversalIdType" ).addText( "FacilityUniversalIdType" );
        element.addElement( "personLocationType" ).addText( "PersonLocationType" );
        element.addElement( "locationDescription" ).addText( locationDescription );

        return element;
    }


    public static Element createPhysicalQuantity( String elementName )
    {
        return createPhysicalQuantity( elementName, "1.0" );
    }


    public static Element createPhysicalQuantity( String elementName, String value )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "value" ).addText( value );
        element.add( createHL72CodedElementLite( "unit", "Unit" ) );

        return element;
    }


    public static Element createMoney( String elementName )
    {
        return createMoney( elementName, "0.0" );
    }


    public static Element createMoney( String elementName, String value )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.add( createHL72CodedElementLite( "currency", "Currency" ) );
        element.addElement( "value" ).addText( value );

        return element;
    }


    public static Element createUsMailingAddress( String elementName )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "line1" ).addText( "Line1" );
        element.addElement( "line2" ).addText( "Line2" );
        element.addElement( "city" ).addText( "City" );
        element.addElement( "postalCode" ).addText( "99999" );
        element.addElement( "country" ).addText( "Country" );
        element.addElement( "state" ).addText( "State" );

        return element;

    }


    private static String trimString( String original, int maxLength )
    {
        return original.substring( 0, original.length() > maxLength ? maxLength : original.length() );
    }


    public static Element createZeroToTenRating( String elementName )
    {
        Element element = DocumentHelper.createElement( elementName );

        element.addElement( "rating" ).addText( "5" );
        element.addElement( "question" ).addText( "Question?" );

        return element;
    }
}
