package org.apache.maven.shared.filtering;

import java.io.FilterReader;
import java.io.IOException;
import java.io.Reader;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;

import org.codehaus.plexus.interpolation.InterpolationException;
import org.codehaus.plexus.interpolation.Interpolator;
import org.codehaus.plexus.interpolation.RecursionInterceptor;
import org.codehaus.plexus.interpolation.SimpleRecursionInterceptor;
import org.codehaus.plexus.interpolation.multi.DelimiterSpecification;

/**
 * A FilterReader implementation, that works with Interpolator interface instead of it's own interpolation
 * implementation. This implementation is heavily based on org.codehaus.plexus.util.InterpolationFilterReader.
 *
 * @author cstamas
 * @author Olivier Lamy
 * @version $Id$
 * @since 1.0-beta-5
 */
public class MultiDelimiterInterpolatorFilterReaderLineEnding
    extends FilterReader
{

    /** Interpolator used to interpolate */
    private Interpolator interpolator;

    private RecursionInterceptor recursionInterceptor;

    /** replacement text from a token */
    private String replaceData = null;

    /** Index into replacement data */
    private int replaceIndex = -1;

    /** Index into previous data */
    private int previousIndex = -1;

    /** Default begin token. */
    public static final String DEFAULT_BEGIN_TOKEN = "${";

    /** Default end token. */
    public static final String DEFAULT_END_TOKEN = "}";
    
    /** true by default to preserve backward comp */
    private boolean interpolateWithPrefixPattern = true;

    private String escapeString;
    
    private boolean useEscape = false;
    
    /** if true escapeString will be preserved \{foo} -> \{foo} */
    private boolean preserveEscapeString = false;
    
    private LinkedHashSet delimiters = new LinkedHashSet();
    
    private DelimiterSpecification currentSpec;

    private String beginToken;

    private String originalBeginToken;

    private String endToken;
    
    private boolean supportMultiLineFiltering;
    
    /**
     * this constructor use default begin token ${ and default end token } 
     * @param in reader to use
     * @param interpolator interpolator instance to use
     */
    public MultiDelimiterInterpolatorFilterReaderLineEnding( Reader in, Interpolator interpolator, boolean supportMultiLineFiltering )
    {
        this( in, interpolator, new SimpleRecursionInterceptor(), supportMultiLineFiltering );
    }
    
    /**
     * @param in reader to use
     * @param interpolator interpolator instance to use
     * @param beginToken start token to use
     * @param endToken end token to use
     * @param ri The {@link RecursionInterceptor} to use to prevent recursive expressions.
     * @since 1.12
     */
    public MultiDelimiterInterpolatorFilterReaderLineEnding( Reader in, Interpolator interpolator, RecursionInterceptor ri, boolean supportMultiLineFiltering )
    {
        super( in );

        this.interpolator = interpolator;
        
        // always cache answers, since we'll be sending in pure expressions, not mixed text.
        this.interpolator.setCacheAnswers( true );
        
        recursionInterceptor = ri;
        
        delimiters.add( DelimiterSpecification.DEFAULT_SPEC );
        
        this.supportMultiLineFiltering = supportMultiLineFiltering;
    }    

    
    public boolean removeDelimiterSpec( String delimiterSpec )
    {
        return delimiters.remove( DelimiterSpecification.parse( delimiterSpec ) );
    }
    
    public MultiDelimiterInterpolatorFilterReaderLineEnding setDelimiterSpecs( HashSet specs )
    {
        delimiters.clear();
        for ( Iterator it = specs.iterator(); it.hasNext(); )
        {
            String spec = (String) it.next();
            delimiters.add( DelimiterSpecification.parse( spec ) );
        }
        
        return this;
    }
    
    /**
     * Skips characters. This method will block until some characters are available, an I/O error occurs, or the end of
     * the stream is reached.
     *
     * @param n The number of characters to skip
     * @return the number of characters actually skipped
     * @exception IllegalArgumentException If <code>n</code> is negative.
     * @exception IOException If an I/O error occurs
     */
    public long skip( long n )
        throws IOException
    {
        if ( n < 0L )
        {
            throw new IllegalArgumentException( "skip value is negative" );
        }

        for ( long i = 0; i < n; i++ )
        {
            if ( read() == -1 )
            {
                return i;
            }
        }
        return n;
    }

    /**
     * Reads characters into a portion of an array. This method will block until some input is available, an I/O error
     * occurs, or the end of the stream is reached.
     *
     * @param cbuf Destination buffer to write characters to. Must not be <code>null</code>.
     * @param off Offset at which to start storing characters.
     * @param len Maximum number of characters to read.
     * @return the number of characters read, or -1 if the end of the stream has been reached
     * @exception IOException If an I/O error occurs
     */
    public int read( char cbuf[], int off, int len )
        throws IOException
    {
        for ( int i = 0; i < len; i++ )
        {
            int ch = read();
            if ( ch == -1 )
            {
                if ( i == 0 )
                {
                    return -1;
                }
                else
                {
                    return i;
                }
            }
            cbuf[off + i] = (char) ch;
        }
        return len;
    }

    /**
     * Returns the next character in the filtered stream, replacing tokens from the original stream.
     *
     * @return the next character in the resulting stream, or -1 if the end of the resulting stream has been reached
     * @exception IOException if the underlying stream throws an IOException during reading
     */
    public int read()
        throws IOException
    {
        if ( replaceIndex != -1 && replaceIndex < replaceData.length() )
        {
            int ch = replaceData.charAt( replaceIndex++ );
            if ( replaceIndex >= replaceData.length() )
            {
                replaceIndex = -1;
            }
            return ch;
        }

        int ch = -1;
        if ( previousIndex != -1 && previousIndex < this.endToken.length() )
        {
            ch = this.endToken.charAt( previousIndex++ );
        }
        else
        {
            ch = in.read();
        }
        if (ch == '\n' && !supportMultiLineFiltering)
        {
            previousIndex = -1;
            return ch;
        }
        boolean inEscape = false;
        
        if ( ( inEscape = ( useEscape && ch == escapeString.charAt( 0 ) ) ) || reselectDelimiterSpec( ch ) )
        {
            StringBuffer key = new StringBuffer( );

            key.append( (char) ch );
            
            // this will happen when we're using an escape string, and ONLY then.
            boolean atEnd = false;

            if ( inEscape )
            {
                for( int i = 0; i < escapeString.length() - 1; i++ )
                {
                    ch = in.read();
                    if ( ch == -1 || ( ch == '\n' && !supportMultiLineFiltering ) )
                    {
                        atEnd = true;
                        break;
                    }
                    
                    key.append( (char) ch );
                }
                
                if ( !atEnd )
                {
                    ch = in.read();
                    if ( !reselectDelimiterSpec( ch ) )
                    {
                        replaceData = key.toString();
                        replaceIndex = 1;
                        return replaceData.charAt( 0 );
                    }
                    else
                    {
                        key.append( (char) ch );
                    }
                }
            }

            int beginTokenMatchPos = 1;
            do
            {
                if ( atEnd )
                {
                    // didn't finish reading the escape string.
                    break;
                }
                
                if ( previousIndex != -1 && previousIndex < this.endToken.length() )
                {
                    ch = this.endToken.charAt( previousIndex++ );
                }
                else
                {
                    ch = in.read();
                }
                if ( ch == '\n' && !supportMultiLineFiltering )
                {
                    // EOL 
                    key.append( (char) ch );
                    break;
                }                
                if ( ch != -1 )
                {
                    key.append( (char) ch );
                    if ( ( beginTokenMatchPos < this.originalBeginToken.length() )
                        && ( ch != this.originalBeginToken.charAt( beginTokenMatchPos ) ) )
                    {
                        ch = -1; // not really EOF but to trigger code below
                        break;
                    }
                }
                else
                {
                    break;
                }
                
                beginTokenMatchPos++;
            }
            while ( ch != this.endToken.charAt( 0 ) );

            // now test endToken
            if ( ch != -1 && ( ch != '\n' && !supportMultiLineFiltering) && this.endToken.length() > 1 )
            {
                int endTokenMatchPos = 1;

                do
                {
                    if ( previousIndex != -1 && previousIndex < this.endToken.length() )
                    {
                        ch = this.endToken.charAt( previousIndex++ );
                    }
                    else
                    {
                        ch = in.read();
                    }

                    if ( ch != -1 )
                    {
                        key.append( (char) ch );

                        if ( ch != this.endToken.charAt( endTokenMatchPos++ ) || ( ch != '\n' && !supportMultiLineFiltering ) )
                        {
                            ch = -1; // not really EOF but to trigger code below
                            break;
                        }

                    }
                    else
                    {
                        break;
                    }
                }
                while ( endTokenMatchPos < this.endToken.length() );
            }

            // There is nothing left to read so we have the situation where the begin/end token
            // are in fact the same and as there is nothing left to read we have got ourselves
            // end of a token boundary so let it pass through.
            if ( ch == -1 || (ch =='\n' && !supportMultiLineFiltering ) )
            {
                replaceData = key.toString();
                replaceIndex = 1;
                return replaceData.charAt( 0 );
            }

            String value = null;
            try
            {
                boolean escapeFound = false;
                if ( useEscape )
                {
                    if ( key.toString().startsWith( beginToken ) )
                    {
                        String keyStr = key.toString();
                        if ( !preserveEscapeString )
                        {
                            value = keyStr.substring( escapeString.length(), keyStr.length() );
                        }
                        else
                        {
                            value = keyStr;
                        }
                        escapeFound = true;
                    }
                }
                if ( !escapeFound )
                {
                    if ( interpolateWithPrefixPattern )
                    {
                        value = interpolator.interpolate( key.toString(), "", recursionInterceptor );
                    }
                    else
                    {
                        value = interpolator.interpolate( key.toString(), recursionInterceptor );
                    }
                }
            }
            catch ( InterpolationException e )
            {
                IllegalArgumentException error = new IllegalArgumentException( e.getMessage() );
                error.initCause( e );

                throw error;
            }

            if ( value != null )
            {
                if ( value.length() != 0 )
                {
                    replaceData = value;
                    replaceIndex = 0;
                }
                return read();
            }
            else
            {
                previousIndex = 0;
                replaceData = key.substring( 0, key.length() - this.endToken.length() );
                replaceIndex = 0;
                return this.beginToken.charAt( 0 );
            }
        }

        return ch;
    }

    private boolean reselectDelimiterSpec( int ch )
    {
        for ( Iterator it = delimiters.iterator(); it.hasNext(); )
        {
            DelimiterSpecification spec = (DelimiterSpecification) it.next();
            if ( ch == spec.getBegin().charAt( 0 ) )
            {
                currentSpec = spec;
                originalBeginToken = currentSpec.getBegin();
                beginToken = useEscape ? escapeString + originalBeginToken : originalBeginToken;
                endToken = currentSpec.getEnd();
                
                return true;
            }
        }
        
        return false;
    }

    public boolean isInterpolateWithPrefixPattern()
    {
        return interpolateWithPrefixPattern;
    }

    public void setInterpolateWithPrefixPattern( boolean interpolateWithPrefixPattern )
    {
        this.interpolateWithPrefixPattern = interpolateWithPrefixPattern;
    }
    public String getEscapeString()
    {
        return escapeString;
    }

    public void setEscapeString( String escapeString )
    {
        // TODO NPE if escapeString is null ?
        if ( escapeString != null && escapeString.length() >= 1 )
        {
            this.escapeString = escapeString;
            this.useEscape = escapeString != null && escapeString.length() >= 1;
        }
    }

    public boolean isPreserveEscapeString()
    {
        return preserveEscapeString;
    }

    public void setPreserveEscapeString( boolean preserveEscapeString )
    {
        this.preserveEscapeString = preserveEscapeString;
    }

    public RecursionInterceptor getRecursionInterceptor()
    {
        return recursionInterceptor;
    }

    public MultiDelimiterInterpolatorFilterReaderLineEnding setRecursionInterceptor( RecursionInterceptor recursionInterceptor )
    {
        this.recursionInterceptor = recursionInterceptor;
        return this;
    }
}
