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;

/**
 *
 */
@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<>();
        strategies.add( new RelativeFileLocatorStrategy( configSource.getBasedir() ) );
        strategies.add( new FileLocatorStrategy() );

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

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

        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<>();
        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;
    }

}
