package org.apache.maven.plugin.docck;

/*
 * 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.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.HeadMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.maven.model.IssueManagement;
import org.apache.maven.model.License;
import org.apache.maven.model.Organization;
import org.apache.maven.model.Prerequisites;
import org.apache.maven.model.Scm;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.plugin.docck.reports.DocumentationReport;
import org.apache.maven.plugin.docck.reports.DocumentationReporter;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.settings.Proxy;
import org.apache.maven.settings.Settings;
import org.apache.maven.shared.model.fileset.FileSet;
import org.apache.maven.shared.model.fileset.util.FileSetManager;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.StringUtils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
 * Performs the heavy lifting for documentation checks. This is designed to be
 * reused for other types of projects, too.
 *
 * @author jdcasey
 */
public abstract class AbstractCheckDocumentationMojo
    extends AbstractMojo
{
    private static final int HTTP_STATUS_200 = 200;

    /**
     */
    @Parameter( property = "reactorProjects", readonly = true, required = true )
    private List<MavenProject> reactorProjects;

    /**
     * An optional location where the results will be written to. If this is
     * not specified the results will be written to the console.
     */
    @Parameter( property = "output" )
    private File output;

    /**
     * Directory where the site source for the project is located.
     *
     * @todo should be determined programmatically
     */
    @Parameter( property = "siteDirectory", defaultValue = "src/site" )
    protected String siteDirectory;

    /**
     * Sets whether this plugin is running in offline or online mode. Also
     * useful when you don't want to verify http URLs.
     */
    @Parameter( property = "settings.offline" )
    private boolean offline;

    /**
     * The current user system settings for use in Maven.
     */
    @Parameter( defaultValue = "${settings}", readonly = true, required = true )
    private Settings settings;

    private HttpClient httpClient;

    private FileSetManager fileSetManager = new FileSetManager();

    private List<String> validUrls = new ArrayList<String>();

    protected AbstractCheckDocumentationMojo()
    {
        String httpUserAgent = "maven-docck-plugin/1.x" + " (Java " + System.getProperty( "java.version" ) + "; "
                + System.getProperty( "os.name" ) + " " + System.getProperty( "os.version" ) + ")";

        httpClient = new HttpClient();

        final int connectionTimeout = 5000;
        httpClient.getHttpConnectionManager().getParams().setConnectionTimeout( connectionTimeout );
        httpClient.getParams().setParameter( HttpMethodParams.USER_AGENT, httpUserAgent );
    }

    protected List<MavenProject> getReactorProjects()
    {
        return reactorProjects;
    }

    public void execute()
        throws MojoExecutionException, MojoFailureException
    {
        setupProxy();

        if ( output != null )
        {
            getLog().info( "Writing documentation check results to: " + output );
        }

        Map<MavenProject, DocumentationReporter> reporters = new LinkedHashMap<MavenProject, DocumentationReporter>();
        boolean hasErrors = false;

        for ( MavenProject project : reactorProjects )
        {
            if ( approveProjectPackaging( project.getPackaging() ) )
            {
                getLog().info( "Checking project: " + project.getName() );

                DocumentationReporter reporter = new DocumentationReporter();

                checkProject( project, reporter );

                if ( !hasErrors && reporter.hasErrors() )
                {
                    hasErrors = true;
                }

                reporters.put( project, reporter );
            }
            else
            {
                getLog().info( "Skipping unsupported project: " + project.getName() );
            }
        }

        String messages;

        messages = buildErrorMessages( reporters );

        if ( !hasErrors )
        {
            messages += "No documentation errors were found.";
        }

        try
        {
            writeMessages( messages, hasErrors );
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "Error writing results to output file: " + output );
        }

        if ( hasErrors )
        {
            String logLocation;
            if ( output == null )
            {
                logLocation = "Please see the console output above for more information.";
            }
            else
            {
                logLocation = "Please see \'" + output + "\' for more information.";
            }

            throw new MojoFailureException( "Documentation problems were found. " + logLocation );
        }
    }

    /**
     * Setup proxy access if needed.
     */
    private void setupProxy()
    {
        Proxy settingsProxy = settings.getActiveProxy();

        if ( settingsProxy != null )
        {
            String proxyUsername = settingsProxy.getUsername();

            String proxyPassword = settingsProxy.getPassword();

            String proxyHost = settingsProxy.getHost();

            int proxyPort = settingsProxy.getPort();

            if ( StringUtils.isNotEmpty( proxyHost ) )
            {
                httpClient.getHostConfiguration().setProxy( proxyHost, proxyPort );

                getLog().info( "Using proxy [" + proxyHost + "] at port [" + proxyPort + "]." );

                if ( StringUtils.isNotEmpty( proxyUsername ) )
                {
                    getLog().info( "Using proxy user [" + proxyUsername + "]." );

                    Credentials creds = new UsernamePasswordCredentials( proxyUsername, proxyPassword );

                    httpClient.getState().setProxyCredentials( new AuthScope( proxyHost, proxyPort ), creds );
                    httpClient.getParams().setAuthenticationPreemptive( true );
                }
            }
        }
    }

    private String buildErrorMessages( Map<MavenProject, DocumentationReporter> reporters )
    {
        String messages = "";
        StringBuilder buffer = new StringBuilder();

        for ( Map.Entry<MavenProject, DocumentationReporter> entry : reporters.entrySet() )
        {
            MavenProject project = entry.getKey();
            DocumentationReporter reporter = entry.getValue();

            if ( !reporter.getMessages().isEmpty() )
            {
                buffer.append( "\no " ).append( project.getName() );
                buffer.append( " (" );
                final int numberOfErrors = reporter.getMessagesByType( DocumentationReport.TYPE_ERROR ).size();
                buffer.append( numberOfErrors ).append( " error" ).append( numberOfErrors == 1 ? "" : "s" );
                buffer.append( ", " );
                final int numberOfWarnings = reporter.getMessagesByType( DocumentationReport.TYPE_WARN ).size();
                buffer.append( numberOfWarnings ).append( " warning" ).append( numberOfWarnings == 1 ? "" : "s" );
                buffer.append( ")" );
                buffer.append( "\n" );

                for ( String error : reporter.getMessages() )
                {
                    buffer.append( "  " ).append( error ).append( "\n" );
                }
            }
        }

        if ( buffer.length() > 0 )
        {
            messages = "The following documentation problems were found:\n" + buffer.toString();
        }

        return messages;
    }

    protected abstract boolean approveProjectPackaging( String packaging );

    /**
     * Writes the text in messages either to a file or to the console.
     *
     * @param messages The message text
     * @param hasErrors If there were any documentation errors
     * @throws IOException
     */
    private void writeMessages( String messages, boolean hasErrors )
        throws IOException
    {
        if ( output != null )
        {
            FileWriter writer = null;

            try
            {
                writer = new FileWriter( output );
                writer.write( messages );
                writer.flush();
            }
            finally
            {
                IOUtil.close( writer );
            }
        }
        else
        {
            if ( hasErrors )
            {
                getLog().error( messages );
            }
            else
            {
                getLog().info( messages );
            }
        }
    }

    private void checkProject( MavenProject project, DocumentationReporter reporter )
    {
        checkPomRequirements( project, reporter );

        checkPackagingSpecificDocumentation( project, reporter );
    }

    private void checkPomRequirements( MavenProject project, DocumentationReporter reporter )
    {
        checkProjectLicenses( project, reporter );

        if ( StringUtils.isEmpty( project.getName() ) )
        {
            reporter.error( "pom.xml is missing the <name> tag." );
        }

        if ( StringUtils.isEmpty( project.getDescription() ) )
        {
            reporter.error( "pom.xml is missing the <description> tag." );
        }

        if ( StringUtils.isEmpty( project.getUrl() ) )
        {
            reporter.error( "pom.xml is missing the <url> tag." );
        }
        else
        {
            checkURL( project.getUrl(), "project site", reporter );
        }

        if ( project.getIssueManagement() == null )
        {
            reporter.error( "pom.xml is missing the <issueManagement> tag." );
        }
        else
        {
            IssueManagement issueMngt = project.getIssueManagement();
            if ( StringUtils.isEmpty( issueMngt.getUrl() ) )
            {
                reporter.error( "pom.xml is missing the <url> tag in <issueManagement>." );
            }
            else
            {
                checkURL( issueMngt.getUrl(), "Issue Management", reporter );
            }
        }

        if ( project.getPrerequisites() == null )
        {
            reporter.error( "pom.xml is missing the <prerequisites> tag." );
        }
        else
        {
            Prerequisites prereq = project.getPrerequisites();
            if ( StringUtils.isEmpty( prereq.getMaven() ) )
            {
                reporter.error( "pom.xml is missing the <prerequisites>/<maven> tag." );
            }
        }

        if ( StringUtils.isEmpty( project.getInceptionYear() ) )
        {
            reporter.error( "pom.xml is missing the <inceptionYear> tag." );
        }

        if ( project.getMailingLists().size() == 0 )
        {
            reporter.warn( "pom.xml has no <mailingLists>/<mailingList> specified." );
        }

        if ( project.getScm() == null )
        {
            reporter.warn( "pom.xml is missing the <scm> tag." );
        }
        else
        {
            Scm scm = project.getScm();
            if ( StringUtils.isEmpty( scm.getConnection() ) && StringUtils.isEmpty( scm.getDeveloperConnection() )
                && StringUtils.isEmpty( scm.getUrl() ) )
            {
                reporter.warn( "pom.xml is missing the child tags under the <scm> tag." );
            }
            else if ( scm.getUrl() != null )
            {
                checkURL( scm.getUrl(), "scm", reporter );
            }
        }

        if ( project.getOrganization() == null )
        {
            reporter.error( "pom.xml is missing the <organization> tag." );
        }
        else
        {
            Organization org = project.getOrganization();
            if ( StringUtils.isEmpty( org.getName() ) )
            {
                reporter.error( "pom.xml is missing the <organization>/<name> tag." );
            }
            else if ( org.getUrl() != null )
            {
                checkURL( org.getUrl(), org.getName() + " site", reporter );
            }
        }
    }

    private void checkProjectLicenses( MavenProject project, DocumentationReporter reporter )
    {
        @SuppressWarnings( "unchecked" )
        List<License> licenses = project.getLicenses();

        if ( licenses == null || licenses.isEmpty() )
        {
            reporter.error( "pom.xml has no <licenses>/<license> specified." );
        }
        else
        {
            for ( License license : licenses )
            {
                if ( StringUtils.isEmpty( license.getName() ) )
                {
                    reporter.error( "pom.xml is missing the <licenses>/<license>/<name> tag." );
                }
                else
                {
                    String url = license.getUrl();
                    if ( StringUtils.isEmpty( url ) )
                    {
                        reporter.error( "pom.xml is missing the <licenses>/<license>/<url> tag for the license \'"
                            + license.getName() + "\'." );
                    }
                    else
                    {
                        checkURL( url, "license \'" + license.getName() + "\'", reporter );
                    }
                }
            }
        }
    }

    private String getURLProtocol( String url )
        throws MalformedURLException
    {
        URL licenseUrl = new URL( url );
        String protocol = licenseUrl.getProtocol();

        if ( protocol != null )
        {
            protocol = protocol.toLowerCase();
        }

        return protocol;
    }

    private void checkURL( String url, String description, DocumentationReporter reporter )
    {
        try
        {
            String protocol = getURLProtocol( url );

            if ( protocol.startsWith( "http" ) )
            {
                if ( offline )
                {
                    reporter.warn( "Cannot verify " + description + " in offline mode with URL: \'" + url + "\'." );
                }
                else if ( !validUrls.contains( url ) )
                {
                    HeadMethod headMethod = new HeadMethod( url );
                    headMethod.setFollowRedirects( true );
                    headMethod.setDoAuthentication( false );

                    try
                    {
                        getLog().debug( "Verifying http url: " + url );
                        if ( httpClient.executeMethod( headMethod ) != HTTP_STATUS_200 )
                        {
                            reporter.error( "Cannot reach " + description + " with URL: \'" + url + "\'." );
                        }
                        else
                        {
                            validUrls.add( url );
                        }
                    }
                    catch ( HttpException e )
                    {
                        reporter.error( "Cannot reach " + description + " with URL: \'" + url + "\'.\nError: "
                            + e.getMessage() );
                    }
                    catch ( IOException e )
                    {
                        reporter.error( "Cannot reach " + description + " with URL: \'" + url + "\'.\nError: "
                            + e.getMessage() );
                    }
                    finally
                    {
                        headMethod.releaseConnection();
                    }
                }
            }
            else
            {
                reporter.warn( "Non-HTTP " + description + " URL not verified." );
            }
        }
        catch ( MalformedURLException e )
        {
            reporter.warn( "The " + description + " appears to have an invalid URL \'" + url + "\'."
                + " Message: \'" + e.getMessage() + "\'. Trying to access it as a file instead." );

            checkFile( url, description, reporter );
        }
    }

    private void checkFile( String url, String description, DocumentationReporter reporter )
    {
        File licenseFile = new File( url );
        if ( !licenseFile.exists() )
        {
            reporter.error( "The " + description + " in file \'" + licenseFile.getPath() + "\' does not exist." );
        }
    }

    protected abstract void checkPackagingSpecificDocumentation( MavenProject project, DocumentationReporter reporter );

    protected boolean findFiles( File siteDirectory, String pattern )
    {
        FileSet fs = new FileSet();
        fs.setDirectory( siteDirectory.getAbsolutePath() );
        fs.setFollowSymlinks( false );

        fs.addInclude( "apt/" + pattern + ".apt" );
        fs.addInclude( "apt/" + pattern + ".apt.vm" );
        fs.addInclude( "xdoc/" + pattern + ".xml" );
        fs.addInclude( "xdoc/" + pattern + ".xml.vm" );
        fs.addInclude( "fml/" + pattern + ".fml" );
        fs.addInclude( "fml/" + pattern + ".fml.vm" );
        fs.addInclude( "resources/" + pattern + ".html" );
        fs.addInclude( "resources/" + pattern + ".html.vm" );

        String[] includedFiles = fileSetManager.getIncludedFiles( fs );

        return includedFiles != null && includedFiles.length > 0;
    }
}
