package org.apache.maven.plugins.war;

/*
 * 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.plugin.testing.stubs.ArtifactStub;
import org.apache.maven.plugins.war.WarExplodedMojo;
import org.apache.maven.plugins.war.stub.MavenProjectArtifactsStub;
import org.codehaus.plexus.util.FileUtils;

import java.io.File;
import java.io.FileFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

/**
 * @author Stephane Nicoll
 */
public abstract class AbstractWarExplodedMojoTest
    extends AbstractWarMojoTest
{

    protected WarExplodedMojo mojo;

    public void setUp()
        throws Exception
    {
        super.setUp();
        mojo = (WarExplodedMojo) lookupMojo( "exploded", getPomFile() );
    }

    /**
     * Returns the pom configuration to use.
     *
     * @return the pom configuration
     */
    protected abstract File getPomFile();

    /**
     * Returns the test directory to use.
     *
     * @return the test directory
     */
    protected abstract File getTestDirectory();

    /**
     * Configures the exploded mojo for the specified test.
     * 
     * If the <tt>sourceFiles</tt> parameter is <tt>null</tt>, sample JSPs are created by default.
     *
     * @param testId the id of the test
     * @param artifactStubs the dependencies (may be null)
     * @param sourceFiles the source files to create (may be null)
     * @return the webapp directory
     * @throws Exception if an error occurs while configuring the mojo
     */
    protected File setUpMojo( final String testId, ArtifactStub[] artifactStubs, String[] sourceFiles )
        throws Exception
    {
        final MavenProjectArtifactsStub project = new MavenProjectArtifactsStub();
        final File webAppDirectory = new File( getTestDirectory(), testId );

        // Create the webapp sources
        File webAppSource;
        if ( sourceFiles == null )
        {
            webAppSource = createWebAppSource( testId );
        }
        else
        {
            webAppSource = createWebAppSource( testId, false );
            for ( String sourceFile : sourceFiles )
            {
                File sample = new File( webAppSource, sourceFile );
                createFile( sample );

            }

        }

        final File classesDir = createClassesDir( testId, true );
        final File workDirectory = new File( getTestDirectory(), "/war/work-" + testId );
        createDir( workDirectory );

        if ( artifactStubs != null )
        {
            for ( ArtifactStub artifactStub : artifactStubs )
            {
                project.addArtifact( artifactStub );
            }
        }

        configureMojo( mojo, new LinkedList<String>(), classesDir, webAppSource, webAppDirectory, project );
        setVariableValueToObject( mojo, "workDirectory", workDirectory );

        return webAppDirectory;
    }

    /**
     * Configures the exploded mojo for the specified test.
     *
     * @param testId the id of the test
     * @param artifactStubs the dependencies (may be null)
     * @return the webapp directory
     * @throws Exception if an error occurs while configuring the mojo
     */
    protected File setUpMojo( final String testId, ArtifactStub[] artifactStubs )
        throws Exception
    {
        return setUpMojo( testId, artifactStubs, null );
    }

    /**
     * Cleans up a directory.
     *
     * @param directory the directory to remove
     * @throws IOException if an error occurred while removing the directory
     */
    protected void cleanDirectory( File directory )
        throws IOException
    {
        if ( directory != null && directory.isDirectory() && directory.exists() )
        {
            FileUtils.deleteDirectory( directory );
        }
    }

    /**
     * Asserts the default content of the war based on the specified webapp directory.
     *
     * @param webAppDirectory the webapp directory
     * @return a list of File objects that have been asserted
     */
    protected List<File> assertDefaultContent( File webAppDirectory )
    {
        // Validate content of the webapp
        File expectedWebSourceFile = new File( webAppDirectory, "pansit.jsp" );
        File expectedWebSource2File = new File( webAppDirectory, "org/web/app/last-exile.jsp" );

        assertTrue( "source file not found: " + expectedWebSourceFile.toString(), expectedWebSourceFile.exists() );
        assertTrue( "source file not found: " + expectedWebSource2File.toString(), expectedWebSource2File.exists() );

        final List<File> content = new ArrayList<File>();
        content.add( expectedWebSourceFile );
        content.add( expectedWebSource2File );

        return content;
    }

    /**
     * Asserts the web.xml file of the war based on the specified webapp directory.
     *
     * @param webAppDirectory the webapp directory
     * @return a list with the web.xml File object
     */
    protected List<File> assertWebXml( File webAppDirectory )
    {
        File expectedWEBXMLFile = new File( webAppDirectory, "WEB-INF/web.xml" );
        assertTrue( "web xml not found: " + expectedWEBXMLFile.toString(), expectedWEBXMLFile.exists() );

        final List<File> content = new ArrayList<File>();
        content.add( expectedWEBXMLFile );

        return content;
    }

    /**
     * Asserts custom content of the war based on the specified webapp directory.
     *
     * @param webAppDirectory the webapp directory
     * @param filePaths an array of file paths relative to the webapp directory
     * @param customMessage a custom message if an assertion fails
     * @return a list of File objects that have been inspected
     */
    protected List<File> assertCustomContent( File webAppDirectory, String[] filePaths, String customMessage )
    {
        final List<File> content = new ArrayList<File>();
        for ( String filePath : filePaths )
        {
            final File expectedFile = new File( webAppDirectory, filePath );
            if ( customMessage != null )
            {
                assertTrue( customMessage + " - " + expectedFile.toString(), expectedFile.exists() );
            }
            else
            {
                assertTrue( "source file not found: " + expectedFile.toString(), expectedFile.exists() );
            }
            content.add( expectedFile );
        }
        return content;
    }

    /**
     * Asserts that the webapp contains only the specified files.
     *
     * @param webAppDirectory the webapp directory
     * @param expectedFiles the expected files
     * @param filter an optional filter to ignore some resources
     */
    protected void assertWebAppContent( File webAppDirectory, List<File> expectedFiles, FileFilter filter )
    {
        final List<File> webAppContent = new ArrayList<File>();
        if ( filter != null )
        {
            buildFilesList( webAppDirectory, filter, webAppContent );
        }
        else
        {
            buildFilesList( webAppDirectory, new FileFilterImpl( webAppDirectory, null ), webAppContent );
        }

        // Now we have the files, sort them.
        Collections.sort( expectedFiles );
        Collections.sort( webAppContent );
        assertEquals( "Invalid webapp content, expected " + expectedFiles.size() + "file(s) " + expectedFiles
            + " but got " + webAppContent.size() + " file(s) " + webAppContent, expectedFiles, webAppContent );
    }

    /**
     * Builds the list of files and directories from the specified dir.
     * 
     * Note that the filter is not used the usual way. If the filter does not accept the current file, it's not added
     * but yet the subdirectories are added if any.
     *
     * @param dir the base directory
     * @param filter the filter
     * @param content the current content, updated recursivly
     */
    private void buildFilesList( final File dir, FileFilter filter, final List<File> content )
    {
        final File[] files = dir.listFiles();

        for ( File file : files )
        {
            // Add the file if the filter is ok with it
            if ( filter.accept( file ) )
            {
                content.add( file );
            }

            // Even if the file is not accepted and is a directory, add it
            if ( file.isDirectory() )
            {
                buildFilesList( file, filter, content );
            }

        }
    }

    class FileFilterImpl
        implements FileFilter
    {

        private final List<String> rejectedFilePaths;

        private final int webAppDirIndex;

        public FileFilterImpl( File webAppDirectory, String[] rejectedFilePaths )
        {
            if ( rejectedFilePaths != null )
            {
                this.rejectedFilePaths = Arrays.asList( rejectedFilePaths );
            }
            else
            {
                this.rejectedFilePaths = new ArrayList<String>();
            }
            this.webAppDirIndex = webAppDirectory.getAbsolutePath().length() + 1;
        }

        public boolean accept( File file )
        {
            String effectiveRelativePath = buildRelativePath( file );
            return !( rejectedFilePaths.contains( effectiveRelativePath ) || file.isDirectory() );
        }

        private String buildRelativePath( File f )
        {
            return f.getAbsolutePath().substring( webAppDirIndex );
        }
    }

}
