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.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.apache.maven.artifact.repository.ArtifactRepository;
import org.apache.maven.artifact.repository.ArtifactRepositoryPolicy;
import org.apache.maven.artifact.repository.MavenArtifactRepository;
import org.apache.maven.artifact.repository.layout.DefaultRepositoryLayout;
import org.apache.maven.artifact.repository.metadata.Metadata;
import org.apache.maven.artifact.repository.metadata.io.xpp3.MetadataXpp3Reader;
import org.apache.maven.artifact.versioning.ArtifactVersion;
import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.reporting.AbstractMavenReport;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

/**
 *
 * @author skygo
 */
public abstract class AbstractDistCheckMojo
    extends AbstractMavenReport
{
    private static final String CONF = "dist-tool.conf";

    private static final String EOL = System.getProperty( "line.separator" );

    /**
     * URL of repository where artifacts are stored. 
     */
    @Parameter( property = "repositoryUrl", defaultValue = "https://repo.maven.apache.org/maven2/" )
    protected String repoBaseUrl;

    /**
     * List of configuration line for specific inspection.
     */
    @Parameter( property = "configurationLines", defaultValue = "" )
    private List<String> configurationLines;

    @Parameter( defaultValue = "${project.build.directory}/dist-tool" )
    protected File failuresDirectory;

    /**
     * list of artifacts repositories.
     */
    protected List<ArtifactRepository> artifactRepositories = new LinkedList<>();

    protected String distributionAreaUrl;

    /**
     * Path in index page mapping, when path is not the classical /artifact-id/ 
     * The configuration in <code>dist-tool.conf</code> looks like this:
     * <pre>artifact-id index-path = /directory/</pre>
     */
    protected Map<String, String> paths = new HashMap<String, String>();

    /**
     * Site url mapping, when site url read in pom doesn't get the expected value 
     * The configuration in <code>dist-tool.conf</code> looks like this:
     * <pre>artifact-id site = site url
     *artifact-id:version site = site url</pre>
     */
    protected Map<String, String> sites = new HashMap<String, String>();

    /**
     * is it index page check mojo?
     * necessary to only check index page information for plugins marked with asterisk * in db,
     * because they are released as part of a global component (archetype, scm, release, ...)
     */
    protected abstract boolean isIndexPageCheck();
    
    protected abstract void checkArtifact( ConfigurationLineInfo request, String repoBase )
        throws MojoExecutionException;

    protected abstract String getFailuresFilename();

    @Override
    public String getOutputName()
    {
        return "dist-tool-" + getFailuresFilename().replace( ".log", "" );
    }

    private void loadConfiguration()
        throws MojoExecutionException
    {
        URL configuration = Thread.currentThread().getContextClassLoader().getResource( CONF );
        try ( BufferedReader in = new BufferedReader( new InputStreamReader( configuration.openStream() ) ) )
        {
            String text;
            while ( ( text = in.readLine() ) != null )
            {
                configurationLines.add( text );
            }
        }
        catch ( IOException e )
        {
            throw new MojoExecutionException( "error while reading " + configuration, e );
        }
    }

    private ArtifactRepositoryPolicy newArtifactRepositoryPolicy( boolean enabled )
    {
        return new ArtifactRepositoryPolicy( enabled, ArtifactRepositoryPolicy.UPDATE_POLICY_ALWAYS,
                                             ArtifactRepositoryPolicy.CHECKSUM_POLICY_WARN );
    }

    @Override
    public void execute()
        throws MojoExecutionException
    {
        ArtifactRepository aa =
            new MavenArtifactRepository( "central", repoBaseUrl, new DefaultRepositoryLayout(),
                                         newArtifactRepositoryPolicy( false ), newArtifactRepositoryPolicy( true ) );
        artifactRepositories.add( aa );

        if ( configurationLines.isEmpty() )
        {
            loadConfiguration();
        }

        File failures = getFailuresFile();
        if ( failures.exists() )
        {
            failures.delete();
        }
        else
        {
            failuresDirectory.mkdirs();
        }

        ConfigurationLineInfo currentGroup = null;
        for ( String line : configurationLines )
        {
            ConfigurationLineInfo aLine = null;

            String trim = line.trim();

            if ( "".equals( trim ) || trim.startsWith( "##" ) )
            {
                // empty line or comment: ignore
                continue;
            }

            getLog().info( line );

            line = trim;

            if ( line.startsWith( ">" ) )
            {
                // parameter
                int index = line.indexOf( '=' );
                if ( index < 0 )
                {
                    throw new MojoExecutionException( "unparseable configuration line, missing '=': " + line );
                }

                String param = line.substring( 1, index ).trim();
                String value = line.substring( index + 1 ).trim();

                if ( "dist-area".equals( param ) )
                {
                    distributionAreaUrl = value;
                }
                else if ( param.contains( " " ) )
                {
                    // parameter for an artifactId
                    index = param.indexOf( ' ' );
                    String artifactId = param.substring( 0, index );
                    param = param.substring( index ).trim();

                    if ( "index-path".equals( param ) )
                    {
                        paths.put( artifactId, value );
                    }
                    else if ( "site".equals( param ) )
                    {
                        sites.put( artifactId, value );
                    }
                    else
                    {
                        throw new MojoExecutionException( "unknown artifact parameter '" + param
                            + "' in configuration line: " + line );
                    }
                }
                else
                {
                    throw new MojoExecutionException( "unparseable configuration line: " + line );
                }

                continue;
            }
            else if ( line.startsWith( "/" ) )
            {
                // definition of a group, in a dist-area directory
                currentGroup = new ConfigurationLineInfo( line.split( " " ) );

                if ( currentGroup.getArtifactId() == null )
                {
                    continue;
                }

                // check group's parent pom artifact
                aLine = currentGroup;
            }
            else
            {
                // artifact definition
                if ( line.startsWith( "*" ) )
                {
                    // special artifact
                    if ( !isIndexPageCheck() )
                    {
                        // not check-index-page mojo, so ignore this artifact
                        continue;
                    }

                    // remove the asterisk before running the check
                    line = line.substring( 1 ).trim();
                }

                try
                {
                    aLine = new ConfigurationLineInfo( currentGroup, line.split( " " ) );
                }
                catch ( InvalidVersionSpecificationException e )
                {
                    throw new MojoExecutionException( e.getMessage() );
                }
            }

            checkArtifact( aLine, getVersion( aLine ) );
        }

        getLog().info( "" );
    }

    private String getVersion( ConfigurationLineInfo aLine )
        throws MojoExecutionException
    {
        String metadataUrl = aLine.getMetadataFileURL( repoBaseUrl );
        try ( InputStream input = new BufferedInputStream( new URL( metadataUrl ).openStream() ) )
        {
            MetadataXpp3Reader metadataReader = new MetadataXpp3Reader();
            Metadata metadata = metadataReader.read( input );

            aLine.setMetadata( metadata );

            String version;
            if ( aLine.getVersionRange() != null )
            {
                if ( aLine.getVersionRange().hasRestrictions() )
                {
                    List<ArtifactVersion> artifactVersions = new ArrayList<>();
                    for ( String versioningVersion : metadata.getVersioning().getVersions() )
                    {
                        artifactVersions.add( new DefaultArtifactVersion( versioningVersion ) );
                    }
                    version = aLine.getVersionRange().matchVersion( artifactVersions ).toString();
                }
                else
                {
                    version = aLine.getVersionRange().getRecommendedVersion().toString();
                }
                aLine.setForceVersion( version );
            }
            else
            {
                version = metadata.getVersioning().getLatest();
            }
            
            if ( getLog().isDebugEnabled() )
            {
                getLog().debug( "  available versions in repository " + repoBaseUrl );
                // revert sort versions (not handling alpha and
                // complex version schemes but more useful versions are displayed left side)
                Collections.sort( metadata.getVersioning().getVersions(), Collections.reverseOrder() );
                getLog().debug( "    " + metadata.getVersioning().getVersions() );
            }

            if ( aLine.getForcedVersion() != null )
            {
                if ( aLine.getVersionRange().hasRestrictions() )
                {
                    getLog().debug( aLine.getGroupId() + ":" + aLine.getArtifactId()
                                        + " metadata latest version value is " + metadata.getVersioning().getLatest()
                                        + " but check was restricted to " + aLine.getVersionRange()
                                        + " which selected " + aLine.getForcedVersion() );
                }
                else
                {
                    getLog().info( aLine.getGroupId() + ":" + aLine.getArtifactId()
                                   + " metadata latest version value is " + metadata.getVersioning().getLatest()
                                   + " but check was manually set to " + aLine.getForcedVersion() );
                }
            }
           
            return version;
        }
        catch ( IOException | XmlPullParserException ex )
        {
            throw new MojoExecutionException( "error while reading " + metadataUrl, ex );
        }
    }

    /**
     * add an error icon.
     *
     * @param sink doxiasink
     */
    public void iconError( Sink sink )
    {
        icon( sink, "icon_error_sml" );
    }
    
    /**
     * add a warning icon.
     *
     * @param sink doxiasink
     */
    public void iconWarning( Sink sink )
    {
        icon( sink, "icon_warning_sml" );
    }
    
    /**
     * add an success icon.
     *
     * @param sink doxiasink
     */
    public void iconSuccess( Sink sink )
    {
        icon( sink, "icon_success_sml" );
    }

    /**
     * add a "remove" icon.
     *
     * @param sink doxiasink
     */
    protected void iconRemove( Sink sink )
    {
        icon( sink, "remove" );
    }

    private void icon( Sink sink, String level )
    {
        sink.figure();
        sink.figureCaption();
        sink.text( level );
        sink.figureCaption_();
        sink.figureGraphics( "images/" + level + ".gif" );
        sink.figure_();
    }
    
    /**
     * Log and add Error line to logs.txt if not configured to ignore the artifact+version
     * 
     * @param cli
     * @param version
     * @param ignore
     * @param message 
     */
    protected void addErrorLine( ConfigurationLineInfo cli, String version, List<String> ignore, String message ) 
    {
        if ( ( ignore != null )
            && ( ignore.contains( cli.getArtifactId() + ':' + version ) || ignore.contains( cli.getArtifactId() ) ) )
        {
            getLog().warn( message );
        }
        else
        {
            getLog().error( message );

            try ( PrintWriter output = new PrintWriter( new FileWriter( getFailuresFile(), true ) ) )
            {
                output.printf( "%s%s", message, EOL );
            }
            catch ( Exception e )
            {
                getLog().error( "Cannot append to " + getFailuresFilename() );
            }
        }
    }

    private File getFailuresFile()
    {
        return new File( failuresDirectory, getFailuresFilename() );
    }
}
