package org.apache.maven.plugins.assembly.format;

/*
 * 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 org.apache.commons.io.input.ReaderInputStream;
import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
import org.apache.maven.plugins.assembly.utils.AssemblyFileUtils;
import org.apache.maven.plugins.assembly.utils.LineEndings;
import org.apache.maven.plugins.assembly.utils.LineEndingsUtils;
import org.apache.maven.shared.filtering.MavenFilteringException;
import org.apache.maven.shared.filtering.MavenReaderFilterRequest;
import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
import org.codehaus.plexus.components.io.resources.PlexusIoResource;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.LinkedHashSet;
import java.util.List;

/**
 *
 */
public class ReaderFormatter
{
    private static Reader createReaderFilter( @Nonnull Reader source, String escapeString, List<String> delimiters,
                                              AssemblerConfigurationSource configSource, boolean isPropertiesFile )
        throws IOException
    {
        try
        {

            MavenReaderFilterRequest filterRequest =
                new MavenReaderFilterRequest( source, true, configSource.getProject(), configSource.getFilters(),
                                              isPropertiesFile, configSource.getMavenSession(), null );
            
            filterRequest.setEscapeString( escapeString );

            // if these are NOT set, just use the defaults, which are '${*}' and '@'.
            if ( delimiters != null && !delimiters.isEmpty() )
            {
                LinkedHashSet<String> delims = new LinkedHashSet<>();
                for ( String delim : delimiters )
                {
                    if ( delim == null )
                    {
                        // FIXME: ${filter:*} could also trigger this condition. Need a better long-term solution.
                        delims.add( "${*}" );
                    }
                    else
                    {
                        delims.add( delim );
                    }
                }

                filterRequest.setDelimiters( delims );
            }
            else
            {
                filterRequest.setDelimiters( filterRequest.getDelimiters() );
            }

            filterRequest.setInjectProjectBuildFilters( configSource.isIncludeProjectBuildFilters() );
            return configSource.getMavenReaderFilter().filter( filterRequest );
        }
        catch ( MavenFilteringException e )
        {
            IOException ioe = new IOException( "Error filtering file '" + source + "': " + e.getMessage(), e );
            throw ioe;
        }
    }


    private static boolean isForbiddenFiletypes( PlexusIoResource plexusIoResource )
    {
        String fileName = plexusIoResource.getName().toLowerCase();
        return ( fileName.endsWith( ".zip" ) || fileName.endsWith( ".jar" ) );
    }

    private static void checkifFileTypeIsAppropriateForLineEndingTransformation( PlexusIoResource plexusIoResource )
        throws IOException
    {
        if ( isForbiddenFiletypes( plexusIoResource ) )
        {
            throw new IOException( "Cannot transform line endings on this kind of file: " + plexusIoResource.getName()
                                       + "\nDoing so is more or less guaranteed to destroy the file, and it indicates"
                                       + " a problem with your assembly descriptor."
                                       + "\nThis error message is new as of 2.5.3. "
                                       + "\nEarlier versions of assembly-plugin will silently destroy your file. "
                                       + "Fix your descriptor" );
        }

    }

    @Nullable
    public static InputStreamTransformer getFileSetTransformers( final AssemblerConfigurationSource configSource,
                                                                 final boolean isFiltered, String fileSetLineEnding )
        throws AssemblyFormattingException
    {
        final LineEndings lineEndingToUse = LineEndingsUtils.getLineEnding( fileSetLineEnding );

        final boolean transformLineEndings = !LineEndings.keep.equals( lineEndingToUse );

        if ( transformLineEndings || isFiltered )
        {
            return new InputStreamTransformer()
            {
                @Override
                @Nonnull
                public InputStream transform( @Nonnull PlexusIoResource plexusIoResource,
                                              @Nonnull InputStream inputStream )
                    throws IOException
                {
                    InputStream result = inputStream;
                    if ( isFiltered )
                    {
                        boolean isPropertyFile = AssemblyFileUtils.isPropertyFile( plexusIoResource.getName() );
                        final String encoding = isPropertyFile ? "ISO-8859-1" : configSource.getEncoding();

                        Reader source = encoding != null
                            ? new InputStreamReader( inputStream, encoding )
                            : new InputStreamReader( inputStream ); // wtf platform encoding ? TODO: Fix this
                        Reader filtered =
                            createReaderFilter( source, configSource.getEscapeString(), configSource.getDelimiters(),
                                                configSource, isPropertyFile );
                        result = encoding != null
                            ? new ReaderInputStream( filtered, encoding )
                            : new ReaderInputStream( filtered );
                    }
                    if ( transformLineEndings )
                    {
                        checkifFileTypeIsAppropriateForLineEndingTransformation( plexusIoResource );
                        result = LineEndingsUtils.lineEndingConverter( result, lineEndingToUse );
                    }
                    return result;
                }
            };
        }
        return null;
    }
}
