/*
 *  Licensed to the Apache Software Foundation (ASF) under one
 *  or more contributor license agreements.  See the NOTICE file
 *  distributed with this work for additional information
 *  regarding copyright ownership.  The ASF licenses this file
 *  to you under the Apache License, Version 2.0 (the
 *  "License"); you may not use this file except in compliance
 *  with the License.  You may obtain a copy of the License at
 *  
 *    http://www.apache.org/licenses/LICENSE-2.0
 *  
 *  Unless required by applicable law or agreed to in writing,
 *  software distributed under the License is distributed on an
 *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 *  KIND, either express or implied.  See the License for the
 *  specific language governing permissions and limitations
 *  under the License. 
 *  
 */
package org.apache.directory.shared.converter.schema;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Writer;
import java.text.ParseException;
import java.util.List;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.directory.shared.i18n.I18n;

import antlr.RecognitionException;
import antlr.TokenStreamException;


/**
 * A reusable wrapper for antlr generated schema parsers.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev$, $Date$
 */
public class SchemaParser
{
    /** The antlr generated parser */
    private antlrSchemaParser parser = null;
    
    /** A pipe into the parser */
    private PipedOutputStream parserIn = null;

    /** A temporary buffer storing the read schema bytes */
    byte[] buf = new byte[128];

    /** The inputStream mapped over the schema file to parse */
    private InputStream schemaIn;
    
    /** The thread used to read the schema */
    private Thread producerThread;

    /**
     * Creates a reusable instance of an SchemaParser.
     *
     * @throws IOException if the pipe cannot be formed
     */
    public SchemaParser() throws IOException
    {
        init();
    }

    /**
     * Initializes a parser and its plumbing.
     *
     * @throws IOException if a pipe cannot be formed.
     */
    public void init() throws IOException
    {
        parserIn = new PipedOutputStream();
        PipedInputStream in = new PipedInputStream();
        parserIn.connect( in );
        antlrSchemaLexer lexer = new antlrSchemaLexer( in );
        parser = new antlrSchemaParser( lexer );
    }

    /**
     * Clear the parser.
     */
    public synchronized void clear()
    {
        parser.clear();
    }

    /**
     * Thread safe method parses an OpenLDAP schemaObject element/object.
     *
     * @param schemaObject the String image of a complete schema object
     */
    public synchronized List<SchemaElement> parse( String schemaObject ) throws IOException, ParseException
    {
        if ( ( schemaObject == null ) || ( schemaObject.trim().equals( "" ) ) )
        {
            throw new ParseException( I18n.err( I18n.ERR_06001 ), 0 );
        }

        schemaIn = new ByteArrayInputStream( schemaObject.getBytes() );

        if ( producerThread == null )
        {
            producerThread = new Thread( new DataProducer() );
        }

        producerThread.start();
        return invokeParser( schemaObject );
    }

    /**
     * Invoke the parser
     * @param schemaName The schema to be parsed
     * @return A list of schema elements 
     * 
     * @throws IOException If the inputStream can't be read
     * @throws ParseException If the parser encounter an error
     */
    private List<SchemaElement> invokeParser( String schemaName ) throws IOException, ParseException
    {
        try
        {
            parser.parseSchema();
            
            return parser.getSchemaElements();
        }
        catch ( RecognitionException re )
        {
            String msg = I18n.err( I18n.ERR_06002, schemaName, ExceptionUtils.getFullStackTrace( re ) );
            init();
            throw new ParseException( msg, re.getColumn() );
        }
        catch ( TokenStreamException tse )
        {
            String msg = I18n.err( I18n.ERR_06002, schemaName, ExceptionUtils.getFullStackTrace( tse ) );
            init();
            throw new ParseException( msg, 0 );
        }
    }

    /**
     * Thread safe method parses a stream of OpenLDAP schemaObject elements/objects.
     *
     * @param schemaIn a stream of schema objects
     */
    public synchronized List<SchemaElement> parse( InputStream schemaIn, Writer out ) throws IOException, ParseException
    {
        this.schemaIn = schemaIn;

        if ( producerThread == null )
        {
            producerThread = new Thread( new DataProducer() );
        }

        producerThread.start();

        return invokeParser( "schema input stream ==> " + schemaIn.toString() );
    }


    /**
     * Thread safe method parses a file of OpenLDAP schemaObject elements/objects.
     *
     * @param schemaFile a file of schema objects
     */
    public synchronized void parse( File schemaFile ) throws IOException, ParseException
    {
        this.schemaIn = new FileInputStream( schemaFile );

        if ( producerThread == null )
        {
            producerThread = new Thread( new DataProducer() );
        }

        producerThread.start();
        invokeParser( "schema file ==> " + schemaFile.getAbsolutePath() );
    }

    /**
     * The thread which read the schema files and fill the
     * temporaru buffer used by the lexical analyzer.
     */
    class DataProducer implements Runnable
    {
        public void run()
        {
            int count = -1;

            try
            {
                while ( ( count = schemaIn.read( buf ) ) != -1 )
                {
                    parserIn.write( buf, 0, count );
                    parserIn.flush();
                }

                // using an input termination token END - need extra space to return
                parserIn.write( "END ".getBytes() );
            }
            catch ( IOException e )
            {
                e.printStackTrace();
            }
        }
    }
}
