package org.apache.maven.plugins.war.util;

/*
 * 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.maven.artifact.Artifact;
import org.apache.maven.model.Dependency;
import org.codehaus.plexus.util.StringUtils;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * Represents the structure of a web application composed of multiple overlays. Each overlay is registered within this
 * structure with the set of files it holds.
 * 
 * Note that this structure is persisted to disk at each invocation to store which owner holds which path (file).
 *
 * @author Stephane Nicoll
 * @version $Id$
 */
public class WebappStructure
{

    private Map<String, PathSet> registeredFiles;

    private List<DependencyInfo> dependenciesInfo;

    private transient PathSet allFiles = new PathSet();

    private transient WebappStructure cache;

    /**
     * Creates a new empty instance.
     *
     * @param dependencies the dependencies of the project
     */
    public WebappStructure( List<Dependency> dependencies )
    {
        this.dependenciesInfo = createDependenciesInfoList( dependencies );
        this.registeredFiles = new HashMap<String, PathSet>();
        this.cache = null;
    }

    /**
     * Creates a new instance with the specified cache.
     *
     * @param dependencies the dependencies of the project
     * @param cache the cache
     */
    public WebappStructure( List<Dependency> dependencies, WebappStructure cache )
    {
        this.dependenciesInfo = createDependenciesInfoList( dependencies );
        this.registeredFiles = new HashMap<String, PathSet>();
        if ( cache == null )
        {
            this.cache = new WebappStructure( dependencies );
        }
        else
        {
            this.cache = cache;
        }
    }

    /**
     * Returns the list of {@link DependencyInfo} for the project.
     *
     * @return the dependencies information of the project
     */
    public List<DependencyInfo> getDependenciesInfo()
    {
        return dependenciesInfo;
    }

    /**
     * Returns the dependencies of the project.
     *
     * @return the dependencies of the project
     */
    public List<Dependency> getDependencies()
    {
        final List<Dependency> result = new ArrayList<Dependency>();
        if ( dependenciesInfo == null )
        {
            return result;
        }
        for ( DependencyInfo dependencyInfo : dependenciesInfo )
        {
            result.add( dependencyInfo.getDependency() );
        }
        return result;
    }

    /**
     * Specify if the specified <tt>path</tt> is registered or not.
     *
     * @param path the relative path from the webapp root directory
     * @return true if the path is registered, false otherwise
     */
    public boolean isRegistered( String path )
    {
        return getFullStructure().contains( path );

    }

    /**
     * Registers the specified path for the specified owner. Returns <tt>true</tt> if the path is not already
     * registered, <tt>false</tt> otherwise.
     *
     * @param id the owner of the path
     * @param path the relative path from the webapp root directory
     * @return true if the file was registered successfully
     */
    public boolean registerFile( String id, String path )
    {
        if ( !isRegistered( path ) )
        {
            doRegister( id, path );
            return true;
        }
        else
        {
            return false;
        }
    }

    /**
     * Forces the registration of the specified path for the specified owner. If the file is not registered yet, a
     * simple registration is performed. If the file already exists, the owner changes to the specified one.
     * <p>
     * Beware that the semantic of the return boolean is different than the one from
     * {@link #registerFile(String, String)}; returns <tt>true</tt> if an owner replacement was made and <tt>false</tt>
     * if the file was simply registered for the first time.</p>
     *
     * @param id the owner of the path
     * @param path the relative path from the webapp root directory
     * @return false if the file did not exist, true if the owner was replaced
     */
    public boolean registerFileForced( String id, String path )
    {
        if ( !isRegistered( path ) )
        {
            doRegister( id, path );
            return false;
        }
        else
        {
            // Force the switch to the new owner
            getStructure( getOwner( path ) ).remove( path );
            getStructure( id ).add( path );
            return true;
        }

    }

    /**
     * Registers the specified path for the specified owner. Invokes the <tt>callback</tt> with the result of the
     * registration.
     *
     * @param id the owner of the path
     * @param path the relative path from the webapp root directory
     * @param callback the callback to invoke with the result of the registration
     * @throws IOException if the callback invocation throws an IOException
     */
    public void registerFile( String id, String path, RegistrationCallback callback )
        throws IOException
    {

        // If the file is already in the current structure, rejects it with the current owner
        if ( isRegistered( path ) )
        {
            callback.refused( id, path, getOwner( path ) );
        }
        else
        {
            doRegister( id, path );
            // This is a new file
            if ( cache.getOwner( path ) == null )
            {
                callback.registered( id, path );

            } // The file already belonged to this owner
            else if ( cache.getOwner( path ).equals( id ) )
            {
                callback.alreadyRegistered( id, path );
            } // The file belongs to another owner and it's known currently
            else if ( getOwners().contains( cache.getOwner( path ) ) )
            {
                callback.superseded( id, path, cache.getOwner( path ) );
            } // The file belongs to another owner and it's unknown
            else
            {
                callback.supersededUnknownOwner( id, path, cache.getOwner( path ) );
            }
        }
    }

    /**
     * Returns the owner of the specified <tt>path</tt>. If the file is not registered, returns <tt>null</tt>
     *
     * @param path the relative path from the webapp root directory
     * @return the owner or <tt>null</tt>.
     */
    public String getOwner( String path )
    {
        if ( !isRegistered( path ) )
        {
            return null;
        }
        else
        {
            for ( final String owner : registeredFiles.keySet() )
            {
                final PathSet structure = getStructure( owner );
                if ( structure.contains( path ) )
                {
                    return owner;
                }

            }
            throw new IllegalStateException( "Should not happen, path [" + path
                + "] is flagged as being registered but was not found." );
        }

    }

    /**
     * Returns the owners. Note that this the returned {@link Set} may be inconsistent since it represents a persistent
     * cache across multiple invocations.
     * <p>
     * For instance, if an overlay was removed in this execution, it will be still be there till the cache is cleaned.
     * This happens when the clean mojo is invoked.
     * </p>
     *
     * @return the list of owners
     */
    public Set<String> getOwners()
    {
        return registeredFiles.keySet();
    }

    /**
     * Returns all paths that have been registered so far.
     *
     * @return all registered path
     */
    public PathSet getFullStructure()
    {
        return allFiles;
    }

    /**
     * Returns the list of registered files for the specified owner.
     *
     * @param id the owner
     * @return the list of files registered for that owner
     */
    public PathSet getStructure( String id )
    {
        PathSet pathSet = registeredFiles.get( id );
        if ( pathSet == null )
        {
            pathSet = new PathSet();
            registeredFiles.put( id, pathSet );
        }
        return pathSet;
    }

    /**
     * Analyze the dependencies of the project using the specified callback.
     *
     * @param callback the callback to use to report the result of the analysis
     */
    public void analyseDependencies( DependenciesAnalysisCallback callback )
    {
        if ( callback == null )
        {
            throw new NullPointerException( "Callback could not be null." );
        }
        if ( cache == null )
        {
            // Could not analyze dependencies without a cache
            return;
        }

        final List<Dependency> currentDependencies = new ArrayList<Dependency>( getDependencies() );
        final List<Dependency> previousDependencies = new ArrayList<Dependency>( cache.getDependencies() );
        final Iterator<Dependency> it = currentDependencies.listIterator();
        while ( it.hasNext() )
        {
            Dependency dependency = it.next();
            // Check if the dependency is there "as is"

            final Dependency matchingDependency = matchDependency( previousDependencies, dependency );
            if ( matchingDependency != null )
            {
                callback.unchangedDependency( dependency );
                // Handled so let's remove
                it.remove();
                previousDependencies.remove( matchingDependency );
            }
            else
            {
                // Try to get the dependency
                final Dependency previousDep = findDependency( dependency, previousDependencies );
                if ( previousDep == null )
                {
                    callback.newDependency( dependency );
                    it.remove();
                }
                else if ( !dependency.getVersion().equals( previousDep.getVersion() ) )
                {
                    callback.updatedVersion( dependency, previousDep.getVersion() );
                    it.remove();
                    previousDependencies.remove( previousDep );
                }
                else if ( !dependency.getScope().equals( previousDep.getScope() ) )
                {
                    callback.updatedScope( dependency, previousDep.getScope() );
                    it.remove();
                    previousDependencies.remove( previousDep );
                }
                else if ( dependency.isOptional() != previousDep.isOptional() )
                {
                    callback.updatedOptionalFlag( dependency, previousDep.isOptional() );
                    it.remove();
                    previousDependencies.remove( previousDep );
                }
                else
                {
                    callback.updatedUnknown( dependency, previousDep );
                    it.remove();
                    previousDependencies.remove( previousDep );
                }
            }
        }
        for ( Dependency dependency : previousDependencies )
        {
            callback.removedDependency( dependency );
        }
    }

    /**
     * Registers the target file name for the specified artifact.
     *
     * @param artifact the artifact
     * @param targetFileName the target file name
     */
    public void registerTargetFileName( Artifact artifact, String targetFileName )
    {
        if ( dependenciesInfo != null )
        {
            for ( DependencyInfo dependencyInfo : dependenciesInfo )
            {
                if ( WarUtils.isRelated( artifact, dependencyInfo.getDependency() ) )
                {
                    dependencyInfo.setTargetFileName( targetFileName );
                }
            }
        }
    }

    /**
     * Returns the cached target file name that matches the specified dependency, that is the target file name of the
     * previous run.
     * <p>
     * The dependency object may have changed so the comparison is based on basic attributes of the dependency.
     * </p>
     *
     * @param dependency a dependency
     * @return the target file name of the last run for this dependency
     */
    public String getCachedTargetFileName( Dependency dependency )
    {
        if ( cache == null )
        {
            return null;
        }
        for ( DependencyInfo dependencyInfo : cache.getDependenciesInfo() )
        {
            final Dependency dependency2 = dependencyInfo.getDependency();
            if ( StringUtils.equals( dependency.getGroupId(), dependency2.getGroupId() )
                && StringUtils.equals( dependency.getArtifactId(), dependency2.getArtifactId() )
                && StringUtils.equals( dependency.getType(), dependency2.getType() )
                && StringUtils.equals( dependency.getClassifier(), dependency2.getClassifier() ) )
            {

                return dependencyInfo.getTargetFileName();

            }
        }
        return null;
    }

    // Private helpers

    private void doRegister( String id, String path )
    {
        getFullStructure().add( path );
        getStructure( id ).add( path );
    }

    /**
     * Find a dependency that is similar from the specified dependency.
     *
     * @param dependency the dependency to find
     * @param dependencies a list of dependencies
     * @return a similar dependency or <tt>null</tt> if no similar dependency is found
     */
    private Dependency findDependency( Dependency dependency, List<Dependency> dependencies )
    {
        // CHECKSTYLE_OFF: LineLength
        for ( Dependency dep : dependencies )
        {
            if ( dependency.getGroupId().equals( dep.getGroupId() )
                && dependency.getArtifactId().equals( dep.getArtifactId() )
                && dependency.getType().equals( dep.getType() )
                && ( 
                        ( dependency.getClassifier() == null && dep.getClassifier() == null ) 
                     || ( dependency.getClassifier() != null && dependency.getClassifier().equals( dep.getClassifier() ) ) ) )
            {
                return dep;
            }
        }
        return null;
        // CHECKSTYLE_ON: LineLength
    }

    private Dependency matchDependency( List<Dependency> dependencies, Dependency dependency )
    {
        for ( Dependency dep : dependencies )
        {
            if ( WarUtils.dependencyEquals( dep, dependency ) )
            {
                return dep;
            }

        }
        return null;
    }

    private List<DependencyInfo> createDependenciesInfoList( List<Dependency> dependencies )
    {
        if ( dependencies == null )
        {
            return Collections.emptyList();
        }
        final List<DependencyInfo> result = new ArrayList<DependencyInfo>();
        for ( Dependency dependency : dependencies )
        {
            result.add( new DependencyInfo( dependency ) );
        }
        return result;
    }

    private Object readResolve()
    {
        // the full structure should be resolved so let's rebuild it
        this.allFiles = new PathSet();
        for ( PathSet pathSet : registeredFiles.values() )
        {
            this.allFiles.addAll( pathSet );
        }
        return this;
    }

    /**
     * Callback interface to handle events related to filepath registration in the webapp.
     */
    public interface RegistrationCallback
    {

        /**
         * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> has been registered successfully.
         * 
         * This means that the <tt>targetFilename</tt> was unknown and has been registered successfully.
         *
         * @param ownerId the ownerId
         * @param targetFilename the relative path according to the root of the webapp
         * @throws IOException if an error occurred while handling this event
         */
        void registered( String ownerId, String targetFilename )
            throws IOException;

        /**
         * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> has already been registered.
         * 
         * This means that the <tt>targetFilename</tt> was known and belongs to the specified owner.
         *
         * @param ownerId the ownerId
         * @param targetFilename the relative path according to the root of the webapp
         * @throws IOException if an error occurred while handling this event
         */
        void alreadyRegistered( String ownerId, String targetFilename )
            throws IOException;

        /**
         * <p>
         * Called if the registration of the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> has been refused
         * since the path already belongs to the <tt>actualOwnerId</tt>.
         * </p> 
         * This means that the <tt>targetFilename</tt> was known and does not belong to the specified owner.
         *
         * @param ownerId the ownerId
         * @param targetFilename the relative path according to the root of the webapp
         * @param actualOwnerId the actual owner
         * @throws IOException if an error occurred while handling this event
         */
        void refused( String ownerId, String targetFilename, String actualOwnerId )
            throws IOException;

        /**
         * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> has been registered successfully by
         * superseding a <tt>deprecatedOwnerId</tt>, that is the previous owner of the file.
         * 
         * This means that the <tt>targetFilename</tt> was known but for another owner. This usually happens after a
         * project's configuration change. As a result, the file has been registered successfully to the new owner.
         *
         * @param ownerId the ownerId
         * @param targetFilename the relative path according to the root of the webapp
         * @param deprecatedOwnerId the previous owner that does not exist anymore
         * @throws IOException if an error occurred while handling this event
         */
        void superseded( String ownerId, String targetFilename, String deprecatedOwnerId )
            throws IOException;

        /**
         * Called if the <tt>targetFilename</tt> for the specified <tt>ownerId</tt> has been registered successfully by
         * superseding a <tt>unknownOwnerId</tt>, that is an owner that does not exist anymore in the current project.
         * 
         * This means that the <tt>targetFilename</tt> was known but for an owner that does not exist anymore. Hence the
         * file has been registered successfully to the new owner.
         *
         * @param ownerId the ownerId
         * @param targetFilename the relative path according to the root of the webapp
         * @param unknownOwnerId the previous owner that does not exist anymore
         * @throws IOException if an error occurred while handling this event
         */
        void supersededUnknownOwner( String ownerId, String targetFilename, String unknownOwnerId )
            throws IOException;
    }

    /**
     * Callback interface to handle events related to dependencies analysis.
     */
    public interface DependenciesAnalysisCallback
    {

        /**
         * Called if the dependency has not changed since the last build.
         *
         * @param dependency the dependency that hasn't changed
         */
        void unchangedDependency( Dependency dependency );

        /**
         * Called if a new dependency has been added since the last build.
         *
         * @param dependency the new dependency
         */
        void newDependency( Dependency dependency );

        /**
         * Called if the dependency has been removed since the last build.
         *
         * @param dependency the dependency that has been removed
         */
        void removedDependency( Dependency dependency );

        /**
         * Called if the version of the dependency has changed since the last build.
         *
         * @param dependency the dependency
         * @param previousVersion the previous version of the dependency
         */
        void updatedVersion( Dependency dependency, String previousVersion );

        /**
         * Called if the scope of the dependency has changed since the last build.
         *
         * @param dependency the dependency
         * @param previousScope the previous scope
         */
        void updatedScope( Dependency dependency, String previousScope );

        /**
         * Called if the optional flag of the dependency has changed since the last build.
         *
         * @param dependency the dependency
         * @param previousOptional the previous optional flag
         */
        void updatedOptionalFlag( Dependency dependency, boolean previousOptional );

        /**
         * Called if the dependency has been updated for unknown reason.
         *
         * @param dependency the dependency
         * @param previousDep the previous dependency
         */
        void updatedUnknown( Dependency dependency, Dependency previousDep );

    }
}
