package org.apache.maven.dist.tools;

/*
 * 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 java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import org.apache.maven.doxia.markup.HtmlMarkup;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.doxia.sink.SinkEventAttributeSet;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.reporting.MavenReportException;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 * Check presence of source-release.zip in distribution area and central repo
 *
 * @author skygo
 */
@Mojo( name = "check-source-release", requiresProject = false )
public class DistCheckSourceReleaseMojo
        extends AbstractDistCheckMojo
{
    private static final String NOT_IN_DISTRIBUTION_AREA = "_not_in_distribution_area_";

    static final String FAILURES_FILENAME = "check-source-release.log";

    @Override
    boolean isIndexPageCheck()
    {
        return false;
    }

    /**
     * Ignore dist failure for <code>artifactId</code> or <code>artifactId:version</code>
     */
    @Parameter
    protected List<String> ignoreDistFailures;

    protected String getFailuresFilename()
    {
        return FAILURES_FILENAME;
    }

    @Override
    public String getName( Locale locale )
    {
        return "Dist Tool> Check Source Release";
    }

    @Override
    public String getDescription( Locale locale )
    {
        return "Verification of source release";
    }

    private static class CheckSourceReleaseResult
        extends AbstractCheckResult
    {

        private List<String> central;
        private List<String> dist;
        private List<String> distOlder;

        public CheckSourceReleaseResult( ConfigurationLineInfo r, String version )
        {
            super( r, version );
        }

        private void setMissingDistSourceRelease( List<String> checkRepos )
        {
            dist = checkRepos;
        }

        private void setMissingCentralSourceRelease( List<String> checkRepos )
        {
            central = checkRepos;
        }

        private void setDistOlderSourceRelease( List<String> checkRepos )
        {
            distOlder = checkRepos;
        }
    }
    private final List<CheckSourceReleaseResult> results = new LinkedList<>();

    private static class DirectoryStatistics
    {
        final String directory;
        final String groupId;
        int artifactsCount = 0;
        int centralMissing = 0;
        int distError = 0;
        int distMissing = 0;
        int distOlder = 0;

        public DirectoryStatistics( String directory, String groupId )
        {
            this.directory = directory;
            this.groupId = groupId;
        }

        public boolean contains( CheckSourceReleaseResult csrr )
        {
            return csrr.getConfigurationLine().getDirectory().equals( directory );
        }

        public void addArtifact( CheckSourceReleaseResult result )
        {
            artifactsCount++;
            if ( !result.central.isEmpty() )
            {
                centralMissing++;
            }
            if ( result.dist == null )
            {
                return;
            }
            if ( !result.dist.isEmpty() || !result.distOlder.isEmpty() )
            {
                distError++;
            }
            if ( !result.dist.isEmpty() )
            {
                distMissing++;
            }
            if ( !result.distOlder.isEmpty() )
            {
                distOlder++;
            }
        }
    }

    private void reportLine( Sink sink, CheckSourceReleaseResult csrr )
    {
        ConfigurationLineInfo cli = csrr.getConfigurationLine();

        sink.tableRow();
        sink.tableCell();
        sink.anchor( cli.getArtifactId() );
        sink.rawText( cli.getArtifactId() );
        sink.anchor_();
        sink.tableCell_();

        // LATEST column
        sink.tableCell();
        sink.link( cli.getMetadataFileURL( repoBaseUrl ) );
        sink.rawText( csrr.getVersion() );
        sink.link_();
        sink.tableCell_();

        // DATE column
        sink.tableCell();
        sink.rawText( cli.getReleaseDateFromMetadata() );
        sink.tableCell_();

        // dist column
        sink.tableCell();
        if ( csrr.dist != null )
        {
            if ( cli.isSrcBin() )
            {
                String directory = csrr.getVersion() + "/source/";
                sink.link( distributionAreaUrl + cli.getDirectory() + '/' + directory );
                sink.text( directory );
                sink.link_();
            }
            if ( csrr.dist.isEmpty() && csrr.distOlder.isEmpty() )
            {
                sink.text( cli.getSourceReleaseFilename( csrr.getVersion(), true ) );
                iconSuccess( sink );
            }
            StringBuilder cliMissing = new StringBuilder();
            for ( String missing : csrr.dist )
            {
                sink.lineBreak();
                iconError( sink );
                sink.rawText( missing );
                if ( !csrr.central.contains( missing ) )
                {
                    // if the release distribution is in central repository, we can get it from there...
                    cliMissing.append( "\nwget " );
                    cliMissing.append( cli.getVersionnedFolderURL( repoBaseUrl, csrr.getVersion() ) );
                    cliMissing.append( missing );
                    cliMissing.append( "\nsvn add " ).append( missing );
                }
            }
            if ( !cliMissing.toString().isEmpty() )
            {
                sink.lineBreak();
                SinkEventAttributeSet atts = new SinkEventAttributeSet();
                sink.unknown( "pre", new Object[] { new Integer( HtmlMarkup.TAG_TYPE_START ) }, atts );
                sink.text( cliMissing.toString() );
                sink.unknown( "pre", new Object[] { new Integer( HtmlMarkup.TAG_TYPE_END ) }, null );
            }

            StringBuilder cliOlder = new StringBuilder();
            for ( String missing : csrr.distOlder )
            {
                sink.lineBreak();
                iconRemove( sink );
                sink.rawText( missing );
                cliOlder.append( "\nsvn rm " ).append( missing );
            }
            if ( !cliOlder.toString().isEmpty() )
            {
                sink.lineBreak();
                SinkEventAttributeSet atts = new SinkEventAttributeSet();
                sink.unknown( "pre", new Object[] { new Integer( HtmlMarkup.TAG_TYPE_START ) }, atts );
                sink.text( cliOlder.toString() );
                sink.unknown( "pre", new Object[] { new Integer( HtmlMarkup.TAG_TYPE_END ) }, null );
            }
        }

        // central column
        sink.tableCell();
        sink.link( cli.getBaseURL( repoBaseUrl, "" ) );
        sink.text( "<artifactId>" );
        sink.link_();
        sink.text( "/" );
        sink.link( cli.getVersionnedFolderURL( repoBaseUrl, csrr.getVersion() ) );
        sink.text( csrr.getVersion() );
        sink.link_();
        sink.text( "/(source-release)" );
        if ( csrr.central.isEmpty() )
        {
            iconSuccess( sink );
        }
        else
        {
            iconWarning( sink );
        }
        for ( String missing : csrr.central )
        {
            sink.lineBreak();
            iconError( sink );
            sink.rawText( missing );
        }
        sink.tableCell_();

        sink.tableCell_();
        sink.tableRow_();
    }

    @Override
    protected void executeReport( Locale locale )
            throws MavenReportException
    {
        if ( !outputDirectory.exists() )
        {
            outputDirectory.mkdirs();
        }
        try
        {
            this.execute();
        }
        catch ( MojoExecutionException ex )
        {
            throw new MavenReportException( ex.getMessage(), ex );
        }

        DirectoryStatistics stats = new DirectoryStatistics( "", "org.apache.maven" ); // global stats

        List<DirectoryStatistics> statistics = new ArrayList<>();
        DirectoryStatistics current = null;
        for ( CheckSourceReleaseResult csrr : results )
        {
            if ( ( current == null ) || !current.contains( csrr ) )
            {
                current =
                    new DirectoryStatistics( csrr.getConfigurationLine().getDirectory(),
                                             csrr.getConfigurationLine().getGroupId() );
                statistics.add( current );
            }
            current.addArtifact( csrr );
            stats.addArtifact( csrr );
        }

        Sink sink = getSink();
        sink.head();
        sink.title();
        sink.text( "Check source release" );
        sink.title_();
        sink.head_();

        sink.body();
        sink.section1();
        sink.paragraph();
        sink.text( "Check Source Release"
                + " (= <artifactId>-<version>-source-release.zip + .asc + .md5) availability in:" );
        sink.paragraph_();
        sink.list();
        sink.listItem();
        sink.text( "Apache Maven distribution area: " );
        sink.link( distributionAreaUrl );
        sink.text( distributionAreaUrl );
        sink.link_();
        sink.listItem_();
        sink.listItem();
        sink.text( "Maven central repository: " );
        sink.link( repoBaseUrl );
        sink.text( repoBaseUrl );
        sink.link_();
        sink.listItem_();
        sink.list_();
        sink.paragraph();
        sink.text( "Older artifacts exploration is Work In Progress..." );
        sink.paragraph_();
        sink.section1_();
        sink.table();
        sink.tableRow();
        sink.tableHeaderCell();
        sink.rawText( "groupId/artifactId: " + String.valueOf( stats.artifactsCount ) );
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.rawText( "LATEST" );
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.rawText( "DATE" );
        sink.tableHeaderCell_();
        reportStatisticsHeader( stats, sink );
        sink.tableRow_();

        Iterator<DirectoryStatistics> dirs = statistics.iterator();
        current = null;

        for ( CheckSourceReleaseResult csrr : results )
        {
            if ( ( current == null ) || !current.contains( csrr ) )
            {
                current = dirs.next();

                sink.tableRow();
                sink.tableHeaderCell();
                // shorten groupid
                sink.rawText( csrr.getConfigurationLine().getGroupId().replaceAll( "org.apache.maven", "o.a.m" ) + ": "
                    + String.valueOf( current.artifactsCount ) );
                sink.tableHeaderCell_();
                sink.tableHeaderCell();
                sink.rawText( " " );
                sink.tableHeaderCell_();
                sink.tableHeaderCell();
                sink.rawText( " " );
                sink.tableHeaderCell_();
                reportStatisticsHeader( current, sink );
                sink.tableRow_();
            }

            reportLine( sink, csrr );
        }

        sink.table_();
        sink.body_();
        sink.flush();
        sink.close();
    }

    private void reportStatisticsHeader( DirectoryStatistics current, Sink sink )
    {
        sink.tableHeaderCell();
        if ( !NOT_IN_DISTRIBUTION_AREA.equals( current.directory ) )
        {
            sink.link( distributionAreaUrl + current.directory );
            sink.text( "<dist-area>/" + current.directory );
            sink.link_();
            sink.rawText( ": " + String.valueOf( current.artifactsCount - current.distError ) );
            iconSuccess( sink );
            if ( current.distError > 0 )
            {
                sink.rawText( "/" + String.valueOf( current.distError ) );
                iconWarning( sink );
                sink.rawText( "= " + String.valueOf( current.distMissing ) );
                iconError( sink );
                sink.rawText( "/" + String.valueOf( current.distOlder ) );
                iconRemove( sink );
            }
        }
        sink.tableHeaderCell_();
        sink.tableHeaderCell();
        sink.link( repoBaseUrl + current.groupId.replace( '.', '/' ) );
        sink.text( "<central>/" + current.groupId.replace( '.', '/' ).replace( "org/apache/maven", "o/a/m" ) );
        sink.link_();
        sink.rawText( ": " + String.valueOf( current.artifactsCount - current.centralMissing ) );
        iconSuccess( sink );
        if ( current.centralMissing > 0 )
        {
            sink.rawText( "/" + String.valueOf( current.centralMissing ) );
            iconWarning( sink );
        }
        sink.tableHeaderCell_();
    }

    /**
     * Report a pattern for an artifact source release.
     *
     * @param artifact artifact name
     * @return regex
     */
    protected static String getSourceReleasePattern( String artifact )
    {
        /// not the safest
        return "^" + artifact + "-[0-9].*source-release.*$";
    }

    private String cachedUrl;
    private Document cachedDocument;

    private Document read( String url )
        throws IOException
    {
        if ( url.startsWith( distributionAreaUrl ) )
        {
            // distribution area: cache content, since it is read multiple times
            if ( !url.equals( cachedUrl ) )
            {
                cachedUrl = url;
                cachedDocument = Jsoup.connect( url ).get();
            }
            return cachedDocument;
        }
        else
        {
            return Jsoup.connect( url ).get();
        }
    }

    private Elements selectLinks( String repourl )
            throws IOException
    {
        try
        {
            return read( repourl ).select( "a[href]" );
        }
        catch ( IOException ioe )
        {
            throw new IOException( "IOException while reading " + repourl, ioe );
        }
    }

    private List<String> checkContainsOld( String url, ConfigurationLineInfo cli, String version )
            throws IOException
    {
        Elements links = selectLinks( url );

        List<String> retrievedFile = new LinkedList<>();
        for ( Element e : links )
        {
            String art = e.attr( "href" );
            if ( art.matches( getSourceReleasePattern( cli.getArtifactId() ) ) )
            {
                retrievedFile.add( e.attr( "href" ) );
            }
        }

        List<String> expectedFiles = cli.getExpectedFilenames( version, true );

        retrievedFile.removeAll( expectedFiles );

        if ( !retrievedFile.isEmpty() )
        {
            // write the following output in red so it's more readable in jenkins console
            addErrorLine( cli, version, ignoreDistFailures,
                          "Different version than " + version + " for " + cli.getArtifactId() + " available in "
                              + url );
            for ( String sourceItem : retrievedFile )
            {
                addErrorLine( cli, version, ignoreDistFailures, " > " + sourceItem + " <" );
            }
        }

        return retrievedFile;
    }

    /**
     * Check that url points to a directory index containing expected release files
     * @param url
     * @param cli
     * @param version
     * @return missing files
     * @throws IOException
     */
    private List<String> checkDirectoryIndex( String url, ConfigurationLineInfo cli, String version, boolean dist )
            throws IOException
    {
        List<String> retrievedFile = new LinkedList<>();
        Elements links = selectLinks( url );
        for ( Element e : links )
        {
            retrievedFile.add( e.attr( "href" ) );
        }

        List<String> missingFiles;
        // initialize missing files with expected release file names
        missingFiles = cli.getExpectedFilenames( version, dist );

        // removed retrieved files
        missingFiles.removeAll( retrievedFile );

        if ( !missingFiles.isEmpty() )
        {
            addErrorLine( cli, version, ignoreDistFailures, "Missing file for " + cli.getArtifactId() + " in " + url );
            for ( String sourceItem : missingFiles )
            {
                addErrorLine( cli, version, ignoreDistFailures, " > " + sourceItem + " <" );
            }
        }

        return missingFiles;
    }

    @Override
    protected void checkArtifact( ConfigurationLineInfo configLine, String version )
            throws MojoExecutionException
    {
        try
        {
            CheckSourceReleaseResult result = new CheckSourceReleaseResult( configLine, version );
            results.add( result );

            // central
            String centralUrl = configLine.getVersionnedFolderURL( repoBaseUrl, version );
            result.setMissingCentralSourceRelease( checkDirectoryIndex( centralUrl, configLine, version, false ) );

            if ( NOT_IN_DISTRIBUTION_AREA.equals( configLine.getDirectory() ) )
            {
                // no distribution check
                return;
            }

            // dist
            String distUrl =
                distributionAreaUrl + configLine.getDirectory()
                    + ( configLine.isSrcBin() ? ( "/" + version + "/source" ) : "" );
            result.setMissingDistSourceRelease( checkDirectoryIndex( distUrl, configLine, version, true ) );
            result.setDistOlderSourceRelease( checkContainsOld( distUrl, configLine, version ) );
        }
        catch ( IOException ex )
        {
            throw new MojoExecutionException( ex.getMessage(), ex );
        }
    }
}
