/*
 * NIST HL7 Web Service
 * Hl7MessageValidation.java Feb 13, 2007
 *
 * This code was produced by the National Institute of Standards and
 * Technology (NIST). See the "nist.disclaimer" file given in the distribution
 * for information on the use and redistribution of this software.
 */

package gov.nist.hl7.ws.messagevalidation;

import java.util.Map;

import gov.nist.hl7.core.message.AbstractMessage;
import gov.nist.hl7.core.profile.Profile;
import gov.nist.hl7.core.validation.message.MessageValidationContext;
import gov.nist.hl7.core.validation.message.MessageValidationResult;
import gov.nist.hl7.core.validation.message.TableProfileDocument;
import gov.nist.hl7.ws.JdbcRepositoryDao;
import gov.nist.hl7.ws.Logger;

/**
 * @author Roch Bertucat (NIST)
 *
 */
public class Hl7MessageValidation implements Hl7MessageValidationInterface {

    protected Profile profile;
    protected AbstractMessage message;
    protected String report;
    protected MessageValidationContext messageValidContext = null;
    protected String exception = "";
    protected TableProfileDocument resource;
    private MessageValidationUtils mvUtils;
    private JdbcRepositoryDao rDao;

    /* (non-Javadoc)
     * @see gov.nist.hl7.ws.messagevalidation.Hl7MessageValidationInterface#getLastExceptionMessage()
     */
    public String getLastExceptionMessage() {
        String lastException = exception;
        exception = "";
        return lastException;
    }

    /* (non-Javadoc)
     * @see gov.nist.hl7.ws.messagevalidation.Hl7MessageValidationInterface#getServiceStatus()
     */
    public boolean getServiceStatus() {
        boolean ret = true;
        // please do something smart here
        // we'll check the number of active session
        /* if (SessionCounter.getActiveSessions() >= 5) {
            exception += "The number of active Session is too high, please try again later";
        } else if (ret) {
            // then check about the memory usage

        } else {
            ret = true;
        }
        int session = SessionCounter.getActiveSessions();

        long freememory = Runtime.getRuntime().freeMemory();
        Logger.info("Hl7MessageValidationInterface - FreeMemory is " + freememory);
         */

        return ret;
    }

    /* (non-Javadoc)
     * @see gov.nist.hl7.ws.messagevalidation.Hl7MessageValidationInterface#getValidationReport()
     */
    public String getValidationReport() {
        //Logger.info("Hl7MessageValidationInterface - User gets the report");
        if (report == null) {
            report = "Error: Report is null - the Validation may not have been run";
        }
        return report;
    }

    /* (non-Javadoc)
     * @see gov.nist.hl7.ws.messagevalidation.Hl7MessageValidationInterface#loadMessage(java.lang.String)
     */
    public boolean loadMessage(String messageStr) throws Exception {
        try {
            message = mvUtils.getMessage(messageStr);
        } catch (Exception e) {
            exception += e + "\n";
            Logger.fatal(e);
            throw e;
        }
        return true;
    }

    /* (non-Javadoc)
     * @see gov.nist.hl7.ws.messagevalidation.Hl7MessageValidationInterface#loadProfile(java.lang.String)
     */
    public boolean loadProfile(String xmlProfile) throws Exception {
        try {
            profile = mvUtils.getProfile(xmlProfile);
        } catch (Exception e) {
            exception += e + "\n";
            Logger.fatal(e);
            throw e;
        }
        return true;
    }

    /* (non-Javadoc)
     * @see gov.nist.hl7.ws.messagevalidation.Hl7MessageValidationInterface#loadResource(java.lang.String, java.lang.String)
     */
    public boolean loadResource(String xmlResource, String resourceType) throws Exception {
        try {
            resource = TableProfileDocument.Factory.parse(xmlResource);
        } catch (Exception e) {
            exception += e + "\n";
            Logger.fatal(e);
            throw e;
        }
        return true;
    }

    /* (non-Javadoc)
     * @see gov.nist.hl7.ws.messagevalidation.Hl7MessageValidationInterface#setValidationContext(java.lang.String)
     */
    public boolean setValidationContext(String xmlValidationContext) throws Exception {
        try {
            messageValidContext = mvUtils.getMVC(xmlValidationContext);
        } catch (Exception e) {
            exception += e + "\n";
            Logger.fatal(e);
            throw e;
        }
        return true;

    }

    /* (non-Javadoc)
     * @see gov.nist.hl7.ws.messagevalidation.Hl7MessageValidationInterface#useHandle(java.lang.String)
     */
    public boolean useHandle(String oid) throws Exception {
        try {
            Map <String, Object> map = mvUtils.useHandle(oid, rDao);
            resource = (TableProfileDocument) map.get("resource");
            profile = (Profile) map.get("profile");
        } catch (Exception e) {
            exception += e + "\n";
            Logger.fatal(e);
            throw e;
        }
        return true;
    }

    /* (non-Javadoc)
     * @see gov.nist.hl7.ws.messagevalidation.Hl7MessageValidationInterface#useProfile(java.lang.String)
     */
    public boolean useProfile(String oid) throws Exception {
        try {
            profile = rDao.getProfile(oid);
        } catch (Exception e) {
            exception += e + "\n";
            Logger.fatal(e);
            throw e;
        }
        return true;
    }

    /* (non-Javadoc)
     * @see gov.nist.hl7.ws.messagevalidation.Hl7MessageValidationInterface#useResource(java.lang.String)
     */
    public boolean useResource(String oid) throws Exception {
        try {
            resource = rDao.getResource(oid);
        } catch (Exception e) {
            exception += e + "\n";
            Logger.fatal(e);
            throw e;
        }
        return true;
    }

    /* (non-Javadoc)
     * @see gov.nist.hl7.ws.messagevalidation.Hl7MessageValidationInterface#validate()
     */
    public boolean validate() throws Exception {
        boolean ret = false;
        try {
            MessageValidationResult mvResult = mvUtils.validate(profile, message, messageValidContext, resource);
            ret = mvResult.isValid();
            // Get report
            report = mvResult.getReport().toString();

            // clean
            profile = null;
            message = null;
            messageValidContext = null;
            resource = null;
        } catch (Exception e) {
            exception += e + "\n";
            Logger.fatal(e);
            throw e;
        }
        return ret;
    }

    public void setJdbcRepositoryDao(JdbcRepositoryDao inRDao) {
        this.rDao = inRDao;
    }

    public void setMessageValidationUtils(MessageValidationUtils mvUtils) {
        this.mvUtils = mvUtils;
    }
}
