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

/*
 * 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.IOUtils;
import org.apache.maven.plugins.assembly.AssemblerConfigurationSource;
import org.apache.maven.plugins.assembly.InvalidAssemblerConfigurationException;
import org.apache.maven.plugins.assembly.interpolation.AssemblyExpressionEvaluator;
import org.apache.maven.plugins.assembly.interpolation.AssemblyInterpolator;
import org.apache.maven.plugins.assembly.model.Assembly;
import org.apache.maven.plugins.assembly.model.Component;
import org.apache.maven.plugins.assembly.model.ContainerDescriptorHandlerConfig;
import org.apache.maven.plugins.assembly.model.DependencySet;
import org.apache.maven.plugins.assembly.model.FileItem;
import org.apache.maven.plugins.assembly.model.FileSet;
import org.apache.maven.plugins.assembly.model.ModuleSet;
import org.apache.maven.plugins.assembly.model.Repository;
import org.apache.maven.plugins.assembly.model.io.xpp3.AssemblyXpp3Reader;
import org.apache.maven.plugins.assembly.model.io.xpp3.AssemblyXpp3Writer;
import org.apache.maven.plugins.assembly.model.io.xpp3.ComponentXpp3Reader;
import org.apache.maven.plugins.assembly.resolved.AssemblyId;
import org.apache.maven.plugins.assembly.utils.InterpolationConstants;
import org.apache.maven.project.MavenProject;
import org.apache.maven.shared.io.location.ClasspathResourceLocatorStrategy;
import org.apache.maven.shared.io.location.FileLocatorStrategy;
import org.apache.maven.shared.io.location.Location;
import org.apache.maven.shared.io.location.Locator;
import org.apache.maven.shared.io.location.LocatorStrategy;
import org.apache.maven.shared.utils.ReaderFactory;
import org.codehaus.plexus.interpolation.PrefixAwareRecursionInterceptor;
import org.codehaus.plexus.interpolation.RecursionInterceptor;
import org.codehaus.plexus.interpolation.fixed.FixedStringSearchInterpolator;
import org.codehaus.plexus.interpolation.fixed.InterpolationState;
import org.codehaus.plexus.interpolation.fixed.PrefixedObjectValueSource;
import org.codehaus.plexus.interpolation.fixed.PrefixedPropertiesValueSource;
import org.codehaus.plexus.logging.AbstractLogEnabled;
import org.codehaus.plexus.logging.Logger;
import org.codehaus.plexus.logging.console.ConsoleLogger;
import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @version $Id$
 */
@org.codehaus.plexus.component.annotations.Component( role = AssemblyReader.class )
public class DefaultAssemblyReader
    extends AbstractLogEnabled
    implements AssemblyReader
{

    public static FixedStringSearchInterpolator createProjectInterpolator( MavenProject project )
    {
        // CHECKSTYLE_OFF: LineLength
        return FixedStringSearchInterpolator.create( new PrefixedPropertiesValueSource( InterpolationConstants.PROJECT_PROPERTIES_PREFIXES,
                                                                                        project.getProperties(), true ),
                                                     new PrefixedObjectValueSource( InterpolationConstants.PROJECT_PREFIXES,
                                                                                    project, true ) );
        // CHECKSTYLE_ON: LineLength
    }

    @Override
    public List<Assembly> readAssemblies( final AssemblerConfigurationSource configSource )
        throws AssemblyReadException, InvalidAssemblerConfigurationException
    {
        final Locator locator = new Locator();

        final List<LocatorStrategy> strategies = new ArrayList<LocatorStrategy>();
        strategies.add( new RelativeFileLocatorStrategy( configSource.getBasedir() ) );
        strategies.add( new FileLocatorStrategy() );

        final List<LocatorStrategy> refStrategies = new ArrayList<LocatorStrategy>();
        refStrategies.add( new PrefixedClasspathLocatorStrategy( "/assemblies/" ) );

        final List<Assembly> assemblies = new ArrayList<Assembly>();

        final String[] descriptors = configSource.getDescriptors();
        final String[] descriptorRefs = configSource.getDescriptorReferences();
        final File descriptorSourceDirectory = configSource.getDescriptorSourceDirectory();

        if ( ( descriptors != null ) && ( descriptors.length > 0 ) )
        {
            locator.setStrategies( strategies );
            for ( String descriptor1 : descriptors )
            {
                getLogger().info( "Reading assembly descriptor: " + descriptor1 );
                addAssemblyFromDescriptor( descriptor1, locator, configSource, assemblies );
            }
        }

        if ( ( descriptorRefs != null ) && ( descriptorRefs.length > 0 ) )
        {
            locator.setStrategies( refStrategies );
            for ( String descriptorRef : descriptorRefs )
            {
                addAssemblyForDescriptorReference( descriptorRef, configSource, assemblies );
            }
        }

        if ( ( descriptorSourceDirectory != null ) && descriptorSourceDirectory.isDirectory() )
        {
            // CHECKSTYLE_OFF: LineLength
            locator.setStrategies( Collections.<LocatorStrategy>singletonList( new RelativeFileLocatorStrategy( descriptorSourceDirectory ) ) );
            // CHECKSTYLE_ON: LineLength

            final DirectoryScanner scanner = new DirectoryScanner();
            scanner.setBasedir( descriptorSourceDirectory );
            scanner.setIncludes( new String[] { "**/*.xml" } );
            scanner.addDefaultExcludes();

            scanner.scan();

            final String[] paths = scanner.getIncludedFiles();

            for ( String path : paths )
            {
                addAssemblyFromDescriptor( path, locator, configSource, assemblies );
            }
        }

        if ( assemblies.isEmpty() )
        {
            if ( configSource.isIgnoreMissingDescriptor() )
            {
                getLogger().debug( "Ignoring missing assembly descriptors per configuration. "
                    + "See messages above for specifics." );
            }
            else
            {
                throw new AssemblyReadException( "No assembly descriptors found." );
            }
        }

        // check unique IDs
        final Set<String> ids = new HashSet<String>();
        for ( final Assembly assembly : assemblies )
        {
            if ( !ids.add( assembly.getId() ) )
            {
                getLogger().warn( "The assembly id " + assembly.getId() + " is used more than once." );
            }

        }
        return assemblies;
    }

    @Override
    public Assembly getAssemblyForDescriptorReference( final String ref,
                                                       final AssemblerConfigurationSource configSource )
                                                           throws AssemblyReadException,
                                                           InvalidAssemblerConfigurationException
    {
        return addAssemblyForDescriptorReference( ref, configSource, new ArrayList<Assembly>( 1 ) );
    }

    @Override
    public Assembly getAssemblyFromDescriptorFile( final File file, final AssemblerConfigurationSource configSource )
        throws AssemblyReadException, InvalidAssemblerConfigurationException
    {
        return addAssemblyFromDescriptorFile( file, configSource, new ArrayList<Assembly>( 1 ) );
    }

    private Assembly addAssemblyForDescriptorReference( final String ref,
                                                        final AssemblerConfigurationSource configSource,
                                                        final List<Assembly> assemblies )
                                                            throws AssemblyReadException,
                                                            InvalidAssemblerConfigurationException
    {
        final InputStream resourceAsStream = getClass().getResourceAsStream( "/assemblies/" + ref + ".xml" );

        if ( resourceAsStream == null )
        {
            if ( configSource.isIgnoreMissingDescriptor() )
            {
                getLogger().debug( "Ignoring missing assembly descriptor with ID '" + ref + "' per configuration." );
                return null;
            }
            else
            {
                throw new AssemblyReadException( "Descriptor with ID '" + ref + "' not found" );
            }
        }

        Reader reader = null;
        try
        {
            reader = ReaderFactory.newXmlReader( resourceAsStream );
            final Assembly assembly = readAssembly( reader, ref, null, configSource );
            reader.close();
            reader = null;
            assemblies.add( assembly );
            return assembly;
        }
        catch ( final IOException e )
        {
            throw new AssemblyReadException( "Problem with descriptor with ID '" + ref + "'", e );
        }
        finally
        {
            IOUtils.closeQuietly( reader );
        }
    }

    private Assembly addAssemblyFromDescriptorFile( final File descriptor,
                                                    final AssemblerConfigurationSource configSource,
                                                    final List<Assembly> assemblies )
                                                        throws AssemblyReadException,
                                                        InvalidAssemblerConfigurationException
    {
        if ( !descriptor.exists() )
        {
            if ( configSource.isIgnoreMissingDescriptor() )
            {
                getLogger().debug( "Ignoring missing assembly descriptor: '" + descriptor + "' per configuration." );
                return null;
            }
            else
            {
                throw new AssemblyReadException( "Descriptor: '" + descriptor + "' not found" );
            }
        }

        Reader r = null;
        try
        {
            r = ReaderFactory.newXmlReader( descriptor );

            final Assembly assembly =
                readAssembly( r, descriptor.getAbsolutePath(), descriptor.getParentFile(), configSource );

            r.close();
            r = null;

            assemblies.add( assembly );

            return assembly;
        }
        catch ( final IOException e )
        {
            throw new AssemblyReadException( "Error reading assembly descriptor: " + descriptor, e );
        }
        finally
        {
            IOUtil.close( r );
        }
    }

    private Assembly addAssemblyFromDescriptor( final String spec, final Locator locator,
                                                final AssemblerConfigurationSource configSource,
                                                final List<Assembly> assemblies )
                                                    throws AssemblyReadException, InvalidAssemblerConfigurationException
    {
        final Location location = locator.resolve( spec );

        if ( location == null )
        {
            if ( configSource.isIgnoreMissingDescriptor() )
            {
                getLogger().debug( "Ignoring missing assembly descriptor with ID '" + spec
                    + "' per configuration.\nLocator output was:\n\n" + locator.getMessageHolder().render() );
                return null;
            }
            else
            {
                throw new AssemblyReadException( "Error locating assembly descriptor: " + spec + "\n\n"
                    + locator.getMessageHolder().render() );
            }
        }

        Reader r = null;
        try
        {
            r = ReaderFactory.newXmlReader( location.getInputStream() );

            File dir = null;
            if ( location.getFile() != null )
            {
                dir = location.getFile().getParentFile();
            }

            final Assembly assembly = readAssembly( r, spec, dir, configSource );

            r.close();
            r = null;

            assemblies.add( assembly );

            return assembly;
        }
        catch ( final IOException e )
        {
            throw new AssemblyReadException( "Error reading assembly descriptor: " + spec, e );
        }
        finally
        {
            IOUtil.close( r );
        }

    }

    public Assembly readAssembly( Reader reader, final String locationDescription, final File assemblyDir,
                                  final AssemblerConfigurationSource configSource )
        throws AssemblyReadException, InvalidAssemblerConfigurationException
    {
        Assembly assembly;

        final MavenProject project = configSource.getProject();
        try
        {

            InterpolationState is = new InterpolationState();
            final RecursionInterceptor interceptor =
                new PrefixAwareRecursionInterceptor( InterpolationConstants.PROJECT_PREFIXES, true );
            is.setRecursionInterceptor( interceptor );

            FixedStringSearchInterpolator interpolator =
                AssemblyInterpolator.fullInterpolator( project, createProjectInterpolator( project ), configSource );
            AssemblyXpp3Reader.ContentTransformer transformer =
                AssemblyInterpolator.assemblyInterpolator( interpolator, is, getLogger() );

            final AssemblyXpp3Reader r = new AssemblyXpp3Reader( transformer );
            assembly = r.read( reader );

            ComponentXpp3Reader.ContentTransformer ctrans =
                AssemblyInterpolator.componentInterpolator( interpolator, is, getLogger() );
            mergeComponentsWithMainAssembly( assembly, assemblyDir, configSource, ctrans );
            debugPrintAssembly( "After assembly is interpolated:", assembly );

            AssemblyInterpolator.checkErrors( AssemblyId.createAssemblyId( assembly ), is, getLogger() );

            reader.close();
            reader = null;
        }
        catch ( final IOException | XmlPullParserException e )
        {
            throw new AssemblyReadException( "Error reading descriptor: " + locationDescription + ": " + e.getMessage(),
                                             e );
        }
        finally
        {
            IOUtil.close( reader );
        }

        if ( assembly.isIncludeSiteDirectory() )
        {
            includeSiteInAssembly( assembly, configSource );
        }

        return assembly;
    }

    private void debugPrintAssembly( final String message, final Assembly assembly )
    {
        final StringWriter sWriter = new StringWriter();
        try
        {
            new AssemblyXpp3Writer().write( sWriter, assembly );
        }
        catch ( final IOException e )
        {
            getLogger().debug( "Failed to print debug message with assembly descriptor listing, and message: "
                + message, e );
        }

        getLogger().debug( message + "\n\n" + sWriter.toString() + "\n\n" );
    }

    /**
     * Add the contents of all included components to main assembly
     *
     * @param assembly The assembly
     * @param assemblyDir The assembly directory
     * @param transformer The component interpolator
     * @throws AssemblyReadException .
     */
    protected void mergeComponentsWithMainAssembly( final Assembly assembly, final File assemblyDir,
                                                    final AssemblerConfigurationSource configSource,
                                                    ComponentXpp3Reader.ContentTransformer transformer )
                                                        throws AssemblyReadException
    {
        final Locator locator = new Locator();

        if ( assemblyDir != null && assemblyDir.exists() && assemblyDir.isDirectory() )
        {
            locator.addStrategy( new RelativeFileLocatorStrategy( assemblyDir ) );
        }

        // allow absolute paths in componentDescriptor... MASSEMBLY-486
        locator.addStrategy( new RelativeFileLocatorStrategy( configSource.getBasedir() ) );
        locator.addStrategy( new FileLocatorStrategy() );
        locator.addStrategy( new ClasspathResourceLocatorStrategy() );

        final AssemblyExpressionEvaluator aee = new AssemblyExpressionEvaluator( configSource );

        final List<String> componentLocations = assembly.getComponentDescriptors();

        for ( String location : componentLocations )
        {
            // allow expressions in path to component descriptor... MASSEMBLY-486
            try
            {
                location = aee.evaluate( location ).toString();
            }
            catch ( final Exception eee )
            {
                getLogger().error( "Error interpolating componentDescriptor: " + location, eee );
            }

            final Location resolvedLocation = locator.resolve( location );

            if ( resolvedLocation == null )
            {
                throw new AssemblyReadException( "Failed to locate component descriptor: " + location );
            }

            Component component = null;
            Reader reader = null;
            try
            {
                reader = new InputStreamReader( resolvedLocation.getInputStream() );
                component = new ComponentXpp3Reader( transformer ).read( reader );
            }
            catch ( final IOException | XmlPullParserException e )
            {
                throw new AssemblyReadException( "Error reading component descriptor: " + location + " (resolved to: "
                    + resolvedLocation.getSpecification() + ")", e );
            }
            finally
            {
                IOUtil.close( reader );
            }

            mergeComponentWithAssembly( component, assembly );
        }
    }

    /**
     * Add the content of a single Component to main assembly
     *
     * @param component The component
     * @param assembly The assembly
     */
    protected void mergeComponentWithAssembly( final Component component, final Assembly assembly )
    {
        final List<ContainerDescriptorHandlerConfig> containerHandlerDescriptors =
            component.getContainerDescriptorHandlers();

        for ( final ContainerDescriptorHandlerConfig cfg : containerHandlerDescriptors )
        {
            assembly.addContainerDescriptorHandler( cfg );
        }

        final List<DependencySet> dependencySetList = component.getDependencySets();

        for ( final DependencySet dependencySet : dependencySetList )
        {
            assembly.addDependencySet( dependencySet );
        }

        final List<FileSet> fileSetList = component.getFileSets();

        for ( final FileSet fileSet : fileSetList )
        {
            assembly.addFileSet( fileSet );
        }

        final List<FileItem> fileList = component.getFiles();

        for ( final FileItem fileItem : fileList )
        {
            assembly.addFile( fileItem );
        }

        final List<Repository> repositoriesList = component.getRepositories();

        for ( final Repository repository : repositoriesList )
        {
            assembly.addRepository( repository );
        }

        final List<ModuleSet> moduleSets = component.getModuleSets();
        for ( final ModuleSet moduleSet : moduleSets )
        {
            assembly.addModuleSet( moduleSet );
        }
    }

    @Override
    public void includeSiteInAssembly( final Assembly assembly, final AssemblerConfigurationSource configSource )
        throws InvalidAssemblerConfigurationException
    {
        final File siteDirectory = configSource.getSiteDirectory();

        if ( !siteDirectory.exists() )
        {
            throw new InvalidAssemblerConfigurationException( "site did not exist in the target directory - "
                + "please run site:site before creating the assembly" );
        }

        getLogger().info( "Adding site directory to assembly : " + siteDirectory );

        final FileSet siteFileSet = new FileSet();

        siteFileSet.setDirectory( siteDirectory.getPath() );

        siteFileSet.setOutputDirectory( "/site" );

        assembly.addFileSet( siteFileSet );
    }

    @Override
    protected Logger getLogger()
    {
        Logger logger = super.getLogger();

        if ( logger == null )
        {
            logger = new ConsoleLogger( Logger.LEVEL_INFO, "assemblyReader-internal" );
            enableLogging( logger );
        }

        return logger;
    }

}
