package org.apache.maven.shared.filtering;

/*
 * 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.
 */

import static org.junit.Assert.assertEquals;
import static org.mockito.Matchers.eq;
import static org.mockito.Matchers.isA;
import static org.mockito.Mockito.when;

import java.io.Reader;
import java.io.StringReader;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;

import org.codehaus.plexus.interpolation.Interpolator;
import org.codehaus.plexus.interpolation.RecursionInterceptor;
import org.codehaus.plexus.util.IOUtil;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

public class MultiDelimiterInterpolatorFilterReaderLineEndingTest
    extends AbstractInterpolatorFilterReaderLineEndingTest
{

    @Mock
    private Interpolator interpolator;

    @Before
    public void onSetup()
    {
        MockitoAnnotations.initMocks( this );
    }

    @Override
    protected Reader getAaa_AaaReader( Reader in, Interpolator interpolator )
    {
        MultiDelimiterInterpolatorFilterReaderLineEnding reader =
            new MultiDelimiterInterpolatorFilterReaderLineEnding( in, interpolator, true );
        reader.setDelimiterSpecs( Collections.singleton( "aaa*aaa" ) );
        return reader;
    }

    @Override
    protected Reader getAbc_AbcReader( Reader in, Interpolator interpolator )
    {
        MultiDelimiterInterpolatorFilterReaderLineEnding reader =
            new MultiDelimiterInterpolatorFilterReaderLineEnding( in, interpolator, true );
        reader.setDelimiterSpecs( Collections.singleton( "abc*abc" ) );
        return reader;
    }

    @Override
    protected Reader getDollarBracesReader( Reader in, Interpolator interpolator, String escapeString )
    {
        MultiDelimiterInterpolatorFilterReaderLineEnding reader =
            new MultiDelimiterInterpolatorFilterReaderLineEnding( in, interpolator, true );
        reader.setDelimiterSpecs( Collections.singleton( "${*}" ) );
        reader.setEscapeString( escapeString );
        return reader;
    }

    @Override
    protected Reader getAtReader( Reader in, Interpolator interpolator, String escapeString )
    {
        MultiDelimiterInterpolatorFilterReaderLineEnding reader =
            new MultiDelimiterInterpolatorFilterReaderLineEnding( in, interpolator, true );
        reader.setDelimiterSpecs( Collections.singleton( "@" ) );
        reader.setEscapeString( escapeString );
        return reader;
    }

    // MSHARED-199: Filtering doesn't work if 2 delimiters are used on the same line, the first one being left open
    @Test
    public void testLineWithSingleAtAndExpression()
        throws Exception
    {
        when( interpolator.interpolate( eq( "${foo}" ), eq( "" ), isA( RecursionInterceptor.class ) ) ).thenReturn( "bar" );

        Reader in = new StringReader( "toto@titi.com ${foo}" );
        MultiDelimiterInterpolatorFilterReaderLineEnding reader =
            new MultiDelimiterInterpolatorFilterReaderLineEnding( in, interpolator, true );
        reader.setDelimiterSpecs( new HashSet<String>( Arrays.asList( "${*}", "@" ) ) );

        assertEquals( "toto@titi.com bar", IOUtil.toString( reader ) );
    }

    // http://stackoverflow.com/questions/21786805/maven-war-plugin-customize-filter-delimitters-in-webresources/
    @Test
    public void testAtDollarExpression()
        throws Exception
    {
        when( interpolator.interpolate( eq( "${db.server}" ), eq( "" ), isA( RecursionInterceptor.class ) ) ).thenReturn( "DB_SERVER" );
        when( interpolator.interpolate( eq( "${db.port}" ), eq( "" ), isA( RecursionInterceptor.class ) ) ).thenReturn( "DB_PORT" );
        when( interpolator.interpolate( eq( "${db.name}" ), eq( "" ), isA( RecursionInterceptor.class ) ) ).thenReturn( "DB_NAME" );

        Reader in = new StringReader( "  url=\"jdbc:oracle:thin:\\@${db.server}:${db.port}:${db.name}\"" );
        MultiDelimiterInterpolatorFilterReaderLineEnding reader =
            new MultiDelimiterInterpolatorFilterReaderLineEnding( in, interpolator, true );
        reader.setEscapeString( "\\" );
        reader.setDelimiterSpecs( new HashSet<String>( Arrays.asList( "${*}", "@" ) ) );

        assertEquals( "  url=\"jdbc:oracle:thin:@DB_SERVER:DB_PORT:DB_NAME\"", IOUtil.toString( reader ) );
    }
}
