package gov.va.med.cds.clinicaldata;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import gov.va.med.cds.junit.runners.SuiteAwareRunner;

import org.dom4j.Attribute;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.util.Assert;


@RunWith( SuiteAwareRunner.class )
public class DomainClinicalRecordElementHelperTest
{
    private static final String CLINCIAL_RECORD_ELEMENT_NAME = "domainClinicalRecordElement";
    private static final String RECORD_IDENTITY_OWNER = "recordIdentifier.identity";
    private static final String PATIENT_FACILITY_OWNER = "patient.identifier.assigningFacility";
    private static final String FACILITY_VALUE = "200DOD";
    private static final String PATIENT_AUTHORITY_OWNER = "patient.identifier.assigningAuthority";
    private static final String AUTHORITY_VALUE = "USDOD";
    private static final String CHILD_COLLECTION_ONE_NAME = "childOneRecords";
    private static final String CHILD_RECORD_ONE_NAME = "childOneRecord";
    private static final String CHILD_COLLECTION_TWO_NAME = "childTwoRecords";
    private static final String CHILD_RECORD_TWO_NAME = "childTwoRecord";

    @Test
    public void testAddIdToClinicalRecordElement( )
    {
        DomainClinicalRecordElementHelperInterface domainRecordOwner = new DomainClinicalRecordElementHelper();
        domainRecordOwner.setDomainIdentityOwner( RECORD_IDENTITY_OWNER );
        domainRecordOwner.setFacilityOwner( PATIENT_FACILITY_OWNER );
        domainRecordOwner.setAuthorityOwner( PATIENT_AUTHORITY_OWNER );
        
        String parentIdentityValue = "99999";
        Element clinicalRecordElement = buildClinicalRecordElement(parentIdentityValue);
             
        domainRecordOwner.addIdToClinicalRecordElement( clinicalRecordElement );
        
        Element id = clinicalRecordElement.element( "id" );
        Assert.notNull( id );
        Assert.isTrue(id.getText().equals( parentIdentityValue ));
        
        assertFacilityAuthority(domainRecordOwner, clinicalRecordElement);
    }
    
    private void assertFacilityAuthority( DomainClinicalRecordElementHelperInterface domainRecordOwner, Element clinicalRecordElement )
    {
        String facilityValue = domainRecordOwner.getAssigningFacilityValue( clinicalRecordElement );
        Assert.isTrue(facilityValue.equals(FACILITY_VALUE));
        
        String authorityValue = domainRecordOwner.getAssigningAuthorityValue( clinicalRecordElement );
        Assert.isTrue(authorityValue.equals(AUTHORITY_VALUE));
    }

    @Test
    public void testAddIdToParentAndChildElements( )
    {
        HashMap<String,String> childCollectionsAndIdentityOwners = new HashMap<String,String>();
        String child1CollectionKey = CHILD_COLLECTION_ONE_NAME;
        String child2CollectionKey = CHILD_COLLECTION_TWO_NAME;
        childCollectionsAndIdentityOwners.put( child1CollectionKey, RECORD_IDENTITY_OWNER );
        childCollectionsAndIdentityOwners.put( child2CollectionKey, RECORD_IDENTITY_OWNER );
        
        DomainClinicalRecordElementHelperInterface domainRecordOwner = new DomainClinicalRecordElementHelper();
        domainRecordOwner.setDomainIdentityOwner( RECORD_IDENTITY_OWNER );
        domainRecordOwner.setFacilityOwner( PATIENT_FACILITY_OWNER );
        domainRecordOwner.setAuthorityOwner( PATIENT_AUTHORITY_OWNER );
        domainRecordOwner.setChildCollectionsAndIdentityOwners( childCollectionsAndIdentityOwners );
        
        String parentIdentityValue = "9999";
        String child1IdentityValue = "1111";
        String child2IdentityValue = "2222";
        
        Element clinicalRecordElement = buildClinicalRecordElementWithChildren( parentIdentityValue, child1IdentityValue, child2IdentityValue );
      
        domainRecordOwner.addIdToParentAndChildElements( clinicalRecordElement );
        
        Element id = clinicalRecordElement.element( "id" );
        Assert.notNull( id );
        Assert.isTrue(id.getText().equals( parentIdentityValue ));
        
        Element childCollectionOne = clinicalRecordElement.element( CHILD_COLLECTION_ONE_NAME );
        Element childOne = (Element)childCollectionOne.elements().get( 0 );
        Assert.notNull( childOne );
        Element c1Id = childOne.element( "id" );
        Assert.notNull( c1Id );
        Assert.isTrue(c1Id.getText().equals( child1IdentityValue ));
        
        Element childCollectionTwo = clinicalRecordElement.element( CHILD_COLLECTION_TWO_NAME );
        Element childTwo = (Element)childCollectionTwo.elements().get( 0 );
        Assert.notNull( childTwo );
        Element c2Id = childTwo.element( "id" );
        Assert.notNull( c2Id );
        Assert.isTrue(c2Id.getText().equals( child2IdentityValue ));
        
        assertFacilityAuthority(domainRecordOwner, clinicalRecordElement);
                
    }
    
    private Element buildClinicalRecordElement(String identityValue){
        
        Element clinicalRecord = DocumentHelper.createElement(CLINCIAL_RECORD_ELEMENT_NAME);
        clinicalRecord.add( buildRecordIdentifier(identityValue) );
        
        clinicalRecord.add( buildPatient() );
        
        return clinicalRecord;
    }
    
    private Element buildPatient( )
    {
       Element patient = DocumentHelper.createElement("patient");
       Element identifier = DocumentHelper.createElement("identifier");
       Element facility = DocumentHelper.createElement("assigningFacility");
       facility.setText( FACILITY_VALUE );
       Element authority = DocumentHelper.createElement("assigningAuthority");
       authority.setText( AUTHORITY_VALUE );
       identifier.add( facility );
       identifier.add( authority );
       patient.add( identifier );
       return patient;
       
    }

    private Element buildClinicalRecordElementWithChildren(String parentIdentityValue, String child1IdentityValue, String child2IdentitiyValue){
        
        Element parent = buildClinicalRecordElement(parentIdentityValue);
        
        Element child1Collection1 = DocumentHelper.createElement(CHILD_COLLECTION_ONE_NAME);
        Element child1Record1 = DocumentHelper.createElement(CHILD_RECORD_ONE_NAME);
        child1Record1.add( buildRecordIdentifier( child1IdentityValue ) );
        child1Collection1.add( child1Record1 );
        
        Element child1Collection2 = DocumentHelper.createElement(CHILD_COLLECTION_TWO_NAME);
        Element child2Record = DocumentHelper.createElement(CHILD_RECORD_TWO_NAME);
        child2Record.add( buildRecordIdentifier( child2IdentitiyValue ) );
        child1Collection2.add( child2Record );
        
        parent.add( child1Collection1 );
        parent.add( child1Collection2 );
        
        return parent;
    }
    
    private Element buildRecordIdentifier(String identityValue){
        
        Element recordIdentifier = DocumentHelper.createElement("recordIdentifier");
        Element identity = DocumentHelper.createElement("identity");
        identity.setText( identityValue );
        recordIdentifier.add( identity );
        return recordIdentifier;
    }

}
