

package gov.va.med.cds.mediator.work;


import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.DefaultHandler;

import java.io.IOException;
import java.io.StringReader;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.XMLConstants;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import javax.xml.validation.Validator;


public class TemplateValidator
    implements
        ValidatorInterface
{
    private static Log logger = LogFactory.getLog( TemplateValidator.class );
    private final PathMatchingResourcePatternResolver pathResolver = new PathMatchingResourcePatternResolver();
    private static final String TEMPLATE_PATH = "classpath:gov/va/med/cds/templates/";
    private Map<String, Validator> templateValidatorMap = new HashMap<String, Validator>();


    public TemplateValidator( List<String> templateList )
    {
        super();

        try
        {
            SchemaFactory factory = SchemaFactory.newInstance( XMLConstants.W3C_XML_SCHEMA_NS_URI );

            if ( templateList != null )
            {
                for ( String template : templateList )
                {
                    //deployment had a problem finding resources
                    //String templatePath = TEMPLATE_PATH + template + "/**/*.xsd";
                    //Resource[] schemaResources = pathResolver.getResources( templatePath );
                    //URL schemaUrl = schemaResources[schemaResources.length-1].getURL();

                    Resource templateResource = pathResolver.getResource( TEMPLATE_PATH + template + "/template/" + template + ".xsd" );
                    URL schemaUrl = templateResource.getURL();
                    LocalErrorHandler localErrorHandler = new LocalErrorHandler();
                    factory.setErrorHandler( localErrorHandler );
                    Schema compiledSchema = factory.newSchema( schemaUrl );
                    Validator validator = compiledSchema.newValidator();

                    templateValidatorMap.put( template, validator );
                }
            }

        }
        catch ( IOException e )
        {
            String error = "ValidateTemplate Initialization failed IOException: " + e.getMessage();
            System.err.println( error );
            logger.error( error );
        }
        catch ( SAXException e )
        {
            String error = "ValidateTemplate Initialization failed SAXException: " + e.getMessage();
            System.err.println( error );
            logger.error( error );
        }
    }


    public void validate( String aTemplate, String aTemplateId )
        throws Exception
    {
        Validator validator = templateValidatorMap.get( aTemplateId );

        if ( validator != null )
        {
            StreamSource instanceStream = new StreamSource( new StringReader( aTemplate ) );
            validator.validate( instanceStream );
        }
    }

    private class LocalErrorHandler
        extends
            DefaultHandler
        implements
            ErrorHandler
    {
        public void error( SAXParseException e )
        {
            String exceptionMessage = "ValidateTemplate Initialization failed SAXException Error: " + e.getMessage();
            System.err.println( exceptionMessage );
            logger.error( exceptionMessage );
        }


        public void fatalError( SAXParseException e )
        {
            String exceptionMessage = "ValidateTemplate Initialization failed SAXException fatal: " + e.getMessage();
            System.err.println( exceptionMessage );
            logger.fatal( exceptionMessage );
        }


        public void warning( SAXParseException e )
        {
            if ( logger.isWarnEnabled() )
            {
                String exceptionMessage = "ValidateTemplate Initialization failed SAXException fatal: " + e.getMessage();
                System.err.println( exceptionMessage );
                logger.warn( exceptionMessage );
            }
        }
    }

}
