

package gov.va.med.cds.template;


import static org.junit.Assert.assertNotNull;

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

import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.w3c.dom.ls.LSInput;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.sql.Blob;
import java.util.jar.JarInputStream;


/***
 * SchemaResourceResolverTest uses templates in templatecache folder of cds-core
 * project.
 *
 */
@RunWith( SuiteAwareRunner.class )
public class SchemaResourceResolverTest
{

    private static byte[] byteArrayJar = null;
    private static Resource[] jarResources = null;
    private static final String TEMPLATE_JAR_PATH_PATTERN = "file:templatecache/**/AllergiesRead40010.jar";
    private static PathMatchingResourcePatternResolver pathResolver = new PathMatchingResourcePatternResolver();

    private static SchemaResourceResolver schemaResourceResolver = null;


    @BeforeClass
    public static void setUp( )
        throws IOException,
            Exception
    {
        jarResources = pathResolver.getResources( TEMPLATE_JAR_PATH_PATTERN );
        Resource jarResource = jarResources[0];
        byteArrayJar = getBytesFromFile( jarResource.getFile() );
        assertNotNull( byteArrayJar );
        
        Blob blobJar = new javax.sql.rowset.serial.SerialBlob( byteArrayJar );

        schemaResourceResolver = new SchemaResourceResolver( blobJar );
        schemaResourceResolver = new SchemaResourceResolver( new JarInputStream( blobJar.getBinaryStream() ) );

        assertNotNull( schemaResourceResolver );

    }

    @Test
    @Suite( groups = { "checkintest" } )
    public void getSchemaSourceTest( )
    {
        schemaResourceResolver.getSchemaSource();
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void getSchemaSourcesTest( )
    {
        schemaResourceResolver.getSchemaSources();
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void getSchemaMapTest( )
    {
        schemaResourceResolver.getSchemaMap();
    }


    @Test
    @Suite( groups = { "checkintest" } )
    public void resolveResourceTest( )
    {
        LSInput lSInput = schemaResourceResolver.resolveResource( "type", "template/AllergiesRead40010", "publicId", "systemId", "baseURI" );

        lSInput.getBaseURI();
        lSInput.getEncoding();
        lSInput.getPublicId();
        lSInput.getSystemId();
        lSInput.getStringData();
        lSInput.getByteStream();
        lSInput.getCertifiedText();
        lSInput.getCharacterStream();
        lSInput.setBaseURI( "baseURI" );
        lSInput.setByteStream( new ByteArrayInputStream( "resolveResourceTest".getBytes() ) );
        lSInput.setCertifiedText( true );
        lSInput.setCharacterStream( new BufferedReader( new StringReader( "resolveResourceTest" ) ) );
        lSInput.setEncoding( "UTF-8" );
        lSInput.setPublicId( "publicId" );
        lSInput.setStringData( "template/AllergiesRead40010" );
        lSInput.setSystemId( "systemId" );
    }


    /**
     * Returns the contents of the file in a byte array
     * 
     * @param file
     *            File this method should read
     * @return byte[] Returns a byte[] array of the contents of the file
     */
    private static byte[] getBytesFromFile( File file )
        throws IOException
    {

        InputStream is = new FileInputStream( file );

        // Get the size of the file
        long length = file.length();

        /*
         * You cannot create an array using a long type. It needs to be an int
         * type. Before converting to an int type, check to ensure that file is
         * not loarger than Integer.MAX_VALUE;
         */
        if ( length > Integer.MAX_VALUE )
        {
            return null;
        }

        // Create the byte array to hold the data
        byte[] bytes = new byte[( int )length];

        // Read in the bytes
        int offset = 0;
        int numRead = 0;
        while ( ( offset < bytes.length ) && ( ( numRead = is.read( bytes, offset, bytes.length - offset ) ) >= 0 ) )
        {

            offset += numRead;

        }

        // Ensure all the bytes have been read in
        if ( offset < bytes.length )
        {
            throw new IOException( "Could not completely read file " + file.getName() );
        }

        is.close();
        return bytes;

    }

}
