

package gov.va.med.cds.response.strategy;


import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.Node;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;


public class DemographicsBlobStrategy
    extends
        ReferenceMappingVistaResponseBlobStrategy
{

    private static String SKIP_ELEMENT_CREATION = "SKIP_ELEMENT_CREATION";

    Map<String, String> demographicsVistaResponseMetaData;
    Map<String, String> demographicsResponseXmlStructure;


    public void setDemographicsVistaResponseMetaData( Map<String, String> demographicsVistaResponseMetaData )
    {
        this.demographicsVistaResponseMetaData = demographicsVistaResponseMetaData;
    }


    public void setDemographicsResponseXmlStructure( Map<String, String> demographicsResponseXmlStructure )
    {
        this.demographicsResponseXmlStructure = demographicsResponseXmlStructure;
    }


    /***
     * 
     */
    @Override
    public Element formatResponse( List<Map<String, Object>> resultList, String domainEntryPoint, String templateId )
        throws Exception
    {
        resultList = formatResultList( resultList );

        Element results = DocumentHelper.createElement( "results" );

        results.addElement( "demographic" );

        Element demographic = results.element( "demographic" );

        for ( Map<String, Object> map : resultList )
        {
            Document refDoc = getRefDocument( domainEntryPoint, templateId );

            treeWalk( refDoc.getRootElement(), map );

            for ( String elementName : demographicsResponseXmlStructure.keySet() )
            {
                List<Node> nodeList = refDoc.selectNodes( demographicsResponseXmlStructure.get( elementName ) );

                if ( demographic.element( elementName ) == null )
                {
                    for ( Node addNode : nodeList )
                    {
                        if ( elementName.startsWith( SKIP_ELEMENT_CREATION ) )
                        {
                            demographic.add( addNode.detach() );
                        }
                        else
                        {
                            demographic.addElement( elementName ).add( addNode.detach() );
                        }
                    }
                }
                else
                {
                    Element ele = demographic.element( elementName );

                    for ( Node addNode : nodeList )
                    {
                        ele.add( addNode.detach() );
                    }

                }
            }

        }

        return results;
    }


    protected List<Map<String, Object>> formatResultList( List<Map<String, Object>> resultList )
        throws IOException
    {
        Document storedProcResult = null;

        BufferedReader reader = new BufferedReader( new InputStreamReader( new java.io.ByteArrayInputStream( ( byte[] )resultList.get( 0 ).get(
                        "stream" ) ) ) );

        String readLine = null;
        StringBuffer response = new StringBuffer();

        do
        {
            readLine = reader.readLine();

            if ( readLine != null )
            {
                response = response.append( readLine );
            }
        }
        while ( readLine != null );

        List<Map<String, Object>> buildResultList = new ArrayList<Map<String, Object>>();

        try
        {
            storedProcResult = DocumentHelper.parseText( "<results>" + response.toString() + "</results>" );

        }
        catch ( DocumentException e )
        {
            // The response is malformed, return empty 
            return buildResultList;
        }

        Set<String> keySet = demographicsVistaResponseMetaData.keySet();

        // Map column names and column values
        for ( String key : keySet )
        {
            String dataElement = demographicsVistaResponseMetaData.get( key );

            Element elementContainingColumnNames = storedProcResult.getRootElement().element( key );

            String columnNameAsString = elementContainingColumnNames.getText();

            List<Element> dataElements = storedProcResult.getRootElement().elements( dataElement );

            if ( dataElements.size() > 0 )
            {
                String valueAsString = null;

                for ( Element dataElementValue : dataElements )
                {
                    Map<String, Object> newRowMap = new HashMap<String, Object>();

                    valueAsString = dataElementValue.getText();

                    if ( valueAsString.length() > 0 )
                    {
                        Scanner valueScanner = new Scanner( valueAsString ).useDelimiter( "\\^" );

                        Scanner columnNameScanner = new Scanner( columnNameAsString ).useDelimiter( "\\^" );

                        while ( valueScanner.hasNext() )
                        {
                            String colName = columnNameScanner.next();

                            String colValue = valueScanner.next();

                            if ( ( colName != null && colName.length() > 0 ) && ( colValue != null && colValue.length() > 0 ) )
                            {
                                newRowMap.put( colName, colValue );
                            }
                        }

                    }

                    buildResultList.add( newRowMap );
                }

            }

        }

        buildResultList.get( 0 ).put( "SITE ID", ( String )resultList.get( 0 ).get( "siteID" ) );
        buildResultList.get( 0 ).put( "USVHA", "USVHA" );

        return buildResultList;
    }
}
