/*
 * 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.
 */
package org.apache.felix.bundleplugin;


import java.io.File;
import java.io.FilenameFilter;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.jar.Manifest;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.artifact.factory.ArtifactFactory;
import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.resolver.ArtifactCollector;
import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
import org.apache.maven.artifact.resolver.ArtifactResolutionException;
import org.apache.maven.artifact.resolver.ArtifactResolver;
import org.apache.maven.artifact.versioning.VersionRange;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.LifecyclePhase;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.annotations.ResolutionScope;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectBuilder;
import org.apache.maven.project.ProjectBuildingException;
import org.apache.maven.project.artifact.InvalidDependencyVersionException;
import org.apache.maven.shared.dependency.tree.DependencyNode;
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilder;
import org.apache.maven.shared.dependency.tree.DependencyTreeBuilderException;
import org.codehaus.plexus.util.FileUtils;

import aQute.bnd.osgi.Analyzer;
import aQute.bnd.osgi.Jar;


/**
 * Build an OSGi bundle jar for all transitive dependencies.
 *
 * @deprecated The bundleall goal is no longer supported and may be removed in a future release
 */
@Deprecated
@Mojo( name = "bundleall", requiresDependencyResolution = ResolutionScope.TEST, defaultPhase = LifecyclePhase.PACKAGE )
public class BundleAllPlugin extends ManifestPlugin
{
    private static final String LS = System.getProperty( "line.separator" );

    private static final Pattern SNAPSHOT_VERSION_PATTERN = Pattern.compile( "[0-9]{8}_[0-9]{6}_[0-9]+" );

    /**
     * Local repository.
     */
    @Parameter( defaultValue = "${localRepository}", readonly = true, required = true )
    private ArtifactRepository localRepository;

    /**
     * Remote repositories.
     */
    @Parameter( defaultValue = "${project.remoteArtifactRepositories}", readonly = true, required = true )
    private List remoteRepositories;

    /**
     * Import-Package to be used when wrapping dependencies.
     */
    @Parameter( property = "wrapImportPackage", defaultValue = "*" )
    private String wrapImportPackage;

    @Component
    private ArtifactFactory m_factory;

    @Component
    private ArtifactMetadataSource m_artifactMetadataSource;

    @Component
    private ArtifactCollector m_collector;

    /**
     * Artifact resolver, needed to download jars.
     */
    @Component
    private ArtifactResolver m_artifactResolver;

    @Component
    private DependencyTreeBuilder m_dependencyTreeBuilder;

    @Component
    private MavenProjectBuilder m_mavenProjectBuilder;

    /**
     * Ignore missing artifacts that are not required by current project but are required by the
     * transitive dependencies.
     */
    @Parameter
    private boolean ignoreMissingArtifacts;

    private Set m_artifactsBeingProcessed = new HashSet();

    /**
     * Process up to some depth
     */
    @Parameter
    private int depth = Integer.MAX_VALUE;


    @Override
    public void execute() throws MojoExecutionException
    {
        getLog().warn( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );
        getLog().warn( "! The bundleall goal is no longer supported and may be removed in a future release !" );
        getLog().warn( "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~" );

        BundleInfo bundleInfo = bundleAll( getProject() );
        logDuplicatedPackages( bundleInfo );
    }


    /**
     * Bundle a project and all its dependencies
     *
     * @param project
     * @throws MojoExecutionException
     */
    private BundleInfo bundleAll( MavenProject project ) throws MojoExecutionException
    {
        return bundleAll( project, depth );
    }


    /**
     * Bundle a project and its transitive dependencies up to some depth level
     *
     * @param project
     * @param maxDepth how deep to process the dependency tree
     * @throws MojoExecutionException
     */
    protected BundleInfo bundleAll( MavenProject project, int maxDepth ) throws MojoExecutionException
    {
        if ( alreadyBundled( project.getArtifact() ) )
        {
            getLog().debug( "Ignoring project already processed " + project.getArtifact() );
            return null;
        }

        if ( m_artifactsBeingProcessed.contains( project.getArtifact() ) )
        {
            getLog().warn( "Ignoring artifact due to dependency cycle " + project.getArtifact() );
            return null;
        }
        m_artifactsBeingProcessed.add( project.getArtifact() );

        DependencyNode dependencyTree;

        try
        {
            dependencyTree = m_dependencyTreeBuilder.buildDependencyTree( project, localRepository, m_factory,
                m_artifactMetadataSource, null, m_collector );
        }
        catch ( DependencyTreeBuilderException e )
        {
            throw new MojoExecutionException( "Unable to build dependency tree", e );
        }

        BundleInfo bundleInfo = new BundleInfo();

        if ( !dependencyTree.hasChildren() )
        {
            /* no need to traverse the tree */
            return bundleRoot( project, bundleInfo );
        }

        getLog().debug( "Will bundle the following dependency tree" + LS + dependencyTree );

        for ( Iterator it = dependencyTree.inverseIterator(); it.hasNext(); )
        {
            DependencyNode node = ( DependencyNode ) it.next();
            if ( !it.hasNext() )
            {
                /* this is the root, current project */
                break;
            }

            if ( node.getState() != DependencyNode.INCLUDED )
            {
                continue;
            }

            if ( Artifact.SCOPE_SYSTEM.equals( node.getArtifact().getScope() ) )
            {
                getLog().debug( "Ignoring system scoped artifact " + node.getArtifact() );
                continue;
            }

            Artifact artifact;
            try
            {
                artifact = resolveArtifact( node.getArtifact() );
            }
            catch ( ArtifactNotFoundException e )
            {
                if ( ignoreMissingArtifacts )
                {
                    continue;
                }

                throw new MojoExecutionException( "Artifact was not found in the repo" + node.getArtifact(), e );
            }

            node.getArtifact().setFile( artifact.getFile() );

            int nodeDepth = node.getDepth();
            if ( nodeDepth > maxDepth )
            {
                /* node is deeper than we want */
                getLog().debug(
                    "Ignoring " + node.getArtifact() + ", depth is " + nodeDepth + ", bigger than " + maxDepth );
                continue;
            }

            MavenProject childProject;
            try
            {
                childProject = m_mavenProjectBuilder.buildFromRepository( artifact, remoteRepositories,
                    localRepository, true );
                if ( childProject.getDependencyArtifacts() == null )
                {
                    childProject.setDependencyArtifacts( childProject.createArtifacts( m_factory, null, null ) );
                }
            }
            catch ( InvalidDependencyVersionException e )
            {
                throw new MojoExecutionException( "Invalid dependency version for artifact " + artifact );
            }
            catch ( ProjectBuildingException e )
            {
                throw new MojoExecutionException( "Unable to build project object for artifact " + artifact, e );
            }

            childProject.setArtifact( artifact );
            getLog().debug( "Child project artifact location: " + childProject.getArtifact().getFile() );

            if ( ( Artifact.SCOPE_COMPILE.equals( artifact.getScope() ) )
                || ( Artifact.SCOPE_RUNTIME.equals( artifact.getScope() ) ) )
            {
                BundleInfo subBundleInfo = bundleAll( childProject, maxDepth - 1 );
                if ( subBundleInfo != null )
                {
                    bundleInfo.merge( subBundleInfo );
                }
            }
            else
            {
                getLog().debug(
                    "Not processing due to scope (" + childProject.getArtifact().getScope() + "): "
                        + childProject.getArtifact() );
            }
        }

        return bundleRoot( project, bundleInfo );
    }


    /**
     * Bundle the root of a dependency tree after all its children have been bundled
     *
     * @param project
     * @param bundleInfo
     * @return
     * @throws MojoExecutionException
     */
    private BundleInfo bundleRoot( MavenProject project, BundleInfo bundleInfo ) throws MojoExecutionException
    {
        /* do not bundle the project the mojo was called on */
        if ( getProject() != project )
        {
            getLog().debug( "Project artifact location: " + project.getArtifact().getFile() );

            BundleInfo subBundleInfo = bundle( project );
            if ( subBundleInfo != null )
            {
                bundleInfo.merge( subBundleInfo );
            }
        }
        return bundleInfo;
    }


    /**
     * Bundle one project only without building its childre
     *
     * @param project
     * @throws MojoExecutionException
     */
    protected BundleInfo bundle( MavenProject project ) throws MojoExecutionException
    {
        Artifact artifact = project.getArtifact();
        getLog().info( "Bundling " + artifact );

        try
        {
            Map instructions = new LinkedHashMap();
            instructions.put( Analyzer.IMPORT_PACKAGE, wrapImportPackage );

            project.getArtifact().setFile( getFile( artifact ) );
            File outputFile = getOutputFile(artifact);

            if ( project.getArtifact().getFile().equals( outputFile ) )
            {
                /* TODO find the cause why it's getting here */
                return null;
                //                getLog().error(
                //                                "Trying to read and write " + artifact + " to the same file, try cleaning: "
                //                                    + outputFile );
                //                throw new IllegalStateException( "Trying to read and write " + artifact
                //                    + " to the same file, try cleaning: " + outputFile );
            }

            org.apache.maven.shared.dependency.graph.DependencyNode dependencyGraph = buildDependencyGraph( project );
            Analyzer analyzer = getAnalyzer( project, dependencyGraph, instructions, new Properties(), getClasspath( project, dependencyGraph ) );

            Jar osgiJar = new Jar( project.getArtifactId(), project.getArtifact().getFile() );

            outputFile.getAbsoluteFile().getParentFile().mkdirs();

            Collection exportedPackages;
            if ( isOsgi( osgiJar ) )
            {
                /* if it is already an OSGi jar copy it as is */
                getLog().info(
                    "Using existing OSGi bundle for " + project.getGroupId() + ":" + project.getArtifactId() + ":"
                        + project.getVersion() );
                String exportHeader = osgiJar.getManifest().getMainAttributes().getValue( Analyzer.EXPORT_PACKAGE );
                exportedPackages = analyzer.parseHeader( exportHeader ).keySet();
                FileUtils.copyFile( project.getArtifact().getFile(), outputFile );
            }
            else
            {
                /* else generate the manifest from the packages */
                exportedPackages = analyzer.getExports().keySet();
                Manifest manifest = analyzer.getJar().getManifest();
                osgiJar.setManifest( manifest );
                osgiJar.write( outputFile );
            }

            BundleInfo bundleInfo = addExportedPackages( project, exportedPackages );

            // cleanup...
            analyzer.close();
            osgiJar.close();

            return bundleInfo;
        }
        /* too bad Jar.write throws Exception */
        catch ( Exception e )
        {
            throw new MojoExecutionException( "Error generating OSGi bundle for project "
                + getArtifactKey( project.getArtifact() ), e );
        }
    }


    private boolean isOsgi( Jar jar ) throws Exception
    {
        if ( jar.getManifest() != null )
        {
            return jar.getManifest().getMainAttributes().getValue( Analyzer.BUNDLE_NAME ) != null;
        }
        return false;
    }


    private BundleInfo addExportedPackages( MavenProject project, Collection packages )
    {
        BundleInfo bundleInfo = new BundleInfo();
        for ( Iterator it = packages.iterator(); it.hasNext(); )
        {
            String packageName = ( String ) it.next();
            bundleInfo.addExportedPackage( packageName, project.getArtifact() );
        }
        return bundleInfo;
    }


    private String getArtifactKey( Artifact artifact )
    {
        return artifact.getGroupId() + ":" + artifact.getArtifactId();
    }


    private String getBundleName( Artifact artifact )
    {
        return getMaven2OsgiConverter().getBundleFileName( artifact );
    }


    private boolean alreadyBundled( Artifact artifact )
    {
        return getBuiltFile( artifact ) != null;
    }


    /**
     * Use previously built bundles when available.
     *
     * @param artifact
     */
    @Override
    protected File getFile( final Artifact artifact )
    {
        File bundle = getBuiltFile( artifact );

        if ( bundle != null )
        {
            getLog().debug( "Using previously built OSGi bundle for " + artifact + " in " + bundle );
            return bundle;
        }
        return super.getFile( artifact );
    }


    private File getBuiltFile( final Artifact artifact )
    {
        File bundle = null;

        /* if bundle was already built use it instead of jar from repo */
        File outputFile = getOutputFile( artifact );
        if ( outputFile.exists() )
        {
            bundle = outputFile;
        }

        /*
         * Find snapshots in output folder, eg. 2.1-SNAPSHOT will match 2.1.0.20070207_193904_2
         * TODO there has to be another way to do this using Maven libs
         */
        if ( ( bundle == null ) && artifact.isSnapshot() )
        {
            final File buildDirectory = new File( getBuildDirectory() );
            if ( !buildDirectory.exists() )
            {
                buildDirectory.mkdirs();
            }
            File[] files = buildDirectory.listFiles( new FilenameFilter()
            {
                public boolean accept( File dir, String name )
                {
                    if ( dir.equals( buildDirectory ) && snapshotMatch( artifact, name ) )
                    {
                        return true;
                    }
                    return false;
                }
            } );
            if ( files.length > 1 )
            {
                throw new RuntimeException( "More than one previously built bundle matches for artifact " + artifact
                    + " : " + Arrays.asList( files ) );
            }
            if ( files.length == 1 )
            {
                bundle = files[0];
            }
        }

        return bundle;
    }


    /**
     * Check that the bundleName provided correspond to the artifact provided.
     * Used to determine when the bundle name is a timestamped snapshot and the artifact is a snapshot not timestamped.
     *
     * @param artifact artifact with snapshot version
     * @param bundleName bundle file name
     * @return if both represent the same artifact and version, forgetting about the snapshot timestamp
     */
    protected boolean snapshotMatch( Artifact artifact, String bundleName )
    {
        String artifactBundleName = getBundleName( artifact );
        int i = artifactBundleName.indexOf( "SNAPSHOT" );
        if ( i < 0 )
        {
            return false;
        }
        artifactBundleName = artifactBundleName.substring( 0, i );

        if ( bundleName.startsWith( artifactBundleName ) )
        {
            /* it's the same artifact groupId and artifactId */
            String timestamp = bundleName.substring( artifactBundleName.length(), bundleName.lastIndexOf( ".jar" ) );
            Matcher m = SNAPSHOT_VERSION_PATTERN.matcher( timestamp );
            return m.matches();
        }
        return false;
    }


    protected File getOutputFile( Artifact artifact )
    {
        return new File( getOutputDirectory(), getBundleName( artifact ) );
    }


    private Artifact resolveArtifact( Artifact artifact ) throws MojoExecutionException, ArtifactNotFoundException
    {
        VersionRange versionRange;
        if ( artifact.getVersion() != null )
        {
            versionRange = VersionRange.createFromVersion( artifact.getVersion() );
        }
        else
        {
            versionRange = artifact.getVersionRange();
        }

        /*
         * there's a bug with ArtifactFactory#createDependencyArtifact(String, String, VersionRange,
         * String, String, String) that ignores the scope parameter, that's why we use the one with
         * the extra null parameter
         */
        Artifact resolvedArtifact = m_factory.createDependencyArtifact( artifact.getGroupId(),
            artifact.getArtifactId(), versionRange, artifact.getType(), artifact.getClassifier(), artifact.getScope(),
            null );

        try
        {
            m_artifactResolver.resolve( resolvedArtifact, remoteRepositories, localRepository );
        }
        catch ( ArtifactResolutionException e )
        {
            throw new MojoExecutionException( "Error resolving artifact " + resolvedArtifact, e );
        }

        return resolvedArtifact;
    }


    /**
     * Log what packages are exported in more than one bundle
     */
    protected void logDuplicatedPackages( BundleInfo bundleInfo )
    {
        Map duplicatedExports = bundleInfo.getDuplicatedExports();

        for ( Iterator it = duplicatedExports.entrySet().iterator(); it.hasNext(); )
        {
            Map.Entry entry = ( Map.Entry ) it.next();
            String packageName = ( String ) entry.getKey();
            Collection artifacts = ( Collection ) entry.getValue();

            getLog().warn( "Package " + packageName + " is exported in more than a bundle: " );
            for ( Iterator it2 = artifacts.iterator(); it2.hasNext(); )
            {
                Artifact artifact = ( Artifact ) it2.next();
                getLog().warn( "  " + artifact );
            }

        }
    }
}
