/********************************************************************
 * Copyright © 2004 VHA. All rights reserved
 ********************************************************************/
// Package
package gov.va.med.esr.common.report;

// Java classes
import gov.va.med.esr.common.model.lookup.AckType;
import gov.va.med.esr.common.model.lookup.MessageType;
import gov.va.med.esr.common.model.lookup.ReportFormat;
import gov.va.med.esr.common.model.lookup.StandardReport;
import gov.va.med.esr.common.model.report.ReportMessageError;
import gov.va.med.esr.common.model.report.ReportMessageType;
import gov.va.med.esr.common.model.report.ReportParameterSet;
import gov.va.med.esr.common.model.report.ReportSetup;
import gov.va.med.esr.common.report.data.CommonCriteria;
import gov.va.med.esr.service.UnknownLookupCodeException;
import gov.va.med.esr.service.UnknownLookupTypeException;
import gov.va.med.fw.report.ReportExportedType;
import gov.va.med.fw.util.DateUtils;

import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.springframework.orm.hibernate3.HibernateTemplate;

/**
 * SignedApplicationReportTest
 * @created Sep 18, 2006 3:16:43 PM
 * @author DNS   MANSOG
 */
public class HL7ErrorReportTest extends AbstractReportTest {
    private static final String QUERY_NAME_SUMMART_RPT = "hl7ErrorReport.Summary";
    private static final String QUERY_NAME_DETAILED_RPT = "hl7ErrorReport.Detailed";
    
    private Date                startTime  = DateUtils.createCalendar(2000, 1, 1).getTime();
    private Date                endTime    = DateUtils.getCurrentDate();


    /**
     * A default constructor
     * @param testName
     */
    public HL7ErrorReportTest(String testName) {
        super(testName);
    }

    public void testQueryInboundSummary() throws Exception {
        summaryQueryTest("I");
    }
    
    public void testQueryOutboundSummary() throws Exception {
        summaryQueryTest("O");
    }

    private void summaryQueryTest(String direction) {
        String[] paramNamesSummary = new String[] {CommonCriteria.DIRECTION, CommonCriteria.MESSAGE_ERROR, CommonCriteria.START_DATE, CommonCriteria.END_DATE };
        String[] messageError = new String[] {"AE"};
        Object[] paramValues = new Object[] { direction, messageError, startTime, endTime};
        processQuery(QUERY_NAME_SUMMART_RPT, paramNamesSummary, paramValues);

        messageError = new String[] {"AR"};
        paramValues = new Object[] { direction, messageError, startTime, endTime};
        processQuery(QUERY_NAME_SUMMART_RPT, paramNamesSummary, paramValues);
        
        messageError = new String[] {"AE", "AR"};
        paramValues = new Object[] { direction, messageError, startTime, endTime};
        processQuery(QUERY_NAME_SUMMART_RPT, paramNamesSummary, paramValues);
    }

    public void testQueryDetailed() throws Exception {
        String[] paramNamesDetail = new String[] { CommonCriteria.MESSAGE_ERROR, CommonCriteria.MESSAGE_TYPE, CommonCriteria.START_DATE, CommonCriteria.END_DATE };
        String[] messageType = new String[] {MessageType.CODE_ORUZ10_TO_SITE.getCode()};

        String[] messageError = new String[] {"AE"};
        Object[] paramValues = new Object[] {messageError, messageType, startTime, endTime};
        processQuery(QUERY_NAME_DETAILED_RPT, paramNamesDetail, paramValues);

        messageType = new String[] {MessageType.CODE_QRYZ11_TO_ESR.getCode()};
        messageError = new String[] {"AR"};
        paramValues = new Object[] {messageError, messageType, startTime, endTime};
        processQuery(QUERY_NAME_DETAILED_RPT, paramNamesDetail, paramValues);

        messageType = new String[] {MessageType.CODE_ORUZ07_TO_ESR.getCode()};
        messageError = new String[] {"AE", "AR"};
        paramValues = new Object[] {messageError, messageType, startTime, endTime};
        processQuery(QUERY_NAME_DETAILED_RPT, paramNamesDetail, paramValues);
    }

    private void processQuery(String queryName, String[] paramNames, Object[] paramValues) {

        HibernateTemplate tpl = this.getHibernateTemplate();

        List results = tpl.findByNamedQueryAndNamedParam(queryName, paramNames, paramValues);
        assertNotNull(results);

        for (Iterator i = results.iterator(); i.hasNext();) {
            Object row = i.next();
            if (row instanceof Object[]) {
                Object[] elements = (Object[]) row;
                for (int pos = 0; pos < elements.length; pos++) {
                    System.out.println("Element['" + pos + "]: " + elements[pos]);
                }
            } else if (row instanceof Map) {
                Map data = (Map) row;
                for (Iterator iter = data.entrySet().iterator(); iter.hasNext();) {
                    Map.Entry entry = (Map.Entry) iter.next();
                    System.out.println("Key: " + entry.getKey() + " Value: " + entry.getValue());
                }
            } else if (row instanceof List) {
                List data = (List) row;
                for (Iterator iter = data.iterator(); iter.hasNext();) {
                    System.out.println("Value: " + iter.next());
                }
            } else {
                System.out.println("element: " + row);
            }
        }
    }
    
    public void testInboundSumaryView() throws Exception {
        summaryViewTest(StandardReport.CODE_QM_25);
    }
    
    public void testOutboundSumaryView() throws Exception {
        summaryViewTest(StandardReport.CODE_QM_19);
    }

    private void summaryViewTest(StandardReport.Code reportCode) throws UnknownLookupTypeException, UnknownLookupCodeException, Exception {
        ReportSetup setup = new ReportSetup();
        ReportParameterSet parameterSet = new ReportParameterSet();
        
        setup.setReport(this.getStandadReport(reportCode.getCode()));

        parameterSet.setReportFormat(this.getReportFormat(ReportFormat.SUMMARY.getCode()));
        parameterSet.setFileType(this.getReportExportedType(ReportExportedType.PDF.getName()));

        parameterSet.addMessageError(getReportMessageError(AckType.CODE_AE.getCode()));
        parameterSet.addMessageError(getReportMessageError(AckType.CODE_AR.getCode()));
        parameterSet.setFromDate(startTime);
        parameterSet.setToDate(endTime);
        
        setup.setParameterSet(parameterSet);


        this.generateReport(this.getESRUser(), setup);
    }
    
    public void testInboundDetailedView() throws Exception {
        detailedViewTest(StandardReport.CODE_QM_25, MessageType.CODE_ORUZ07_TO_ESR);
    }
    
    public void testOutboundDetailedView() throws Exception {
        detailedViewTest(StandardReport.CODE_QM_19, MessageType.CODE_QRYZ11_TO_MVR);
    }

    private void detailedViewTest(StandardReport.Code reportCode, MessageType.Code msgType) throws UnknownLookupTypeException, UnknownLookupCodeException, Exception {
        ReportSetup setup = new ReportSetup();
        ReportParameterSet parameterSet = new ReportParameterSet();
        
        setup.setReport(this.getStandadReport(reportCode.getCode()));

        parameterSet.setReportFormat(this.getReportFormat(ReportFormat.DETAIL.getCode()));
        parameterSet.setFileType(this.getReportExportedType(ReportExportedType.PDF.getName()));

        parameterSet.addMessageError(getReportMessageError(AckType.CODE_AE.getCode()));
        parameterSet.addMessageError(getReportMessageError(AckType.CODE_AR.getCode()));
        parameterSet.addMessageType(getReportMessageType(msgType.getCode()));
        parameterSet.setFromDate(startTime);
        parameterSet.setToDate(endTime);
        
        setup.setParameterSet(parameterSet);


        this.generateReport(this.getESRUser(), setup);
    }
    
    protected ReportMessageType getReportMessageType(String code ) throws UnknownLookupTypeException, UnknownLookupCodeException {
        ReportMessageType rptMsgType = new ReportMessageType();
        rptMsgType.setMessageType((MessageType) this.getLookupService().getByCode(MessageType.class, code));
        return rptMsgType;
    }
    
    protected ReportMessageError getReportMessageError(String code ) throws UnknownLookupTypeException, UnknownLookupCodeException {
        ReportMessageError rptMsgError = new ReportMessageError();
        rptMsgError.setMessageError((AckType) this.getLookupService().getByCode(AckType.class, code));
        return rptMsgError;
    }
    
    
}