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 java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
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();

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

    /**
     * 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<>();
        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 ( getOwner( path ) == null )
            {
                callback.registered( id, path );

            } // The file already belonged to this owner
            else if ( getOwner( path ).equals( id ) )
            {
                callback.alreadyRegistered( id, path );
            } // The file belongs to another owner and it's known currently
            else if ( getOwners().contains( getOwner( path ) ) )
            {
                callback.superseded( id, path, getOwner( path ) );
            } // The file belongs to another owner and it's unknown
            else
            {
                callback.supersededUnknownOwner( id, path, 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.
     *
     * @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;
    }

    

    /**
     * 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 );
                }
            }
        }
    }

    // Private helpers

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

    private List<DependencyInfo> createDependenciesInfoList( List<Dependency> dependencies )
    {
        if ( dependencies == null )
        {
            return Collections.emptyList();
        }
        final List<DependencyInfo> result = new ArrayList<>();
        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;
    }

}
