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 = "http://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, ...)
     */
    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;

            line = line.trim();

            if ( "".equals( line ) || line.startsWith( "##" ) )
            {
                // empty line or comment: ignore
                continue;
            }
            else 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 ) );
        }
    }

    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( "Checking information for artifact: " + aLine.getGroupId() + ":"
                                    + aLine.getArtifactId() + ":" + version );
                // 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() + " version(s) detected " + repoBaseUrl );
            }

            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
     */
    protected void iconError( Sink sink )
    {
        icon( sink, "icon_error_sml" );
    }
    
    /**
     * add a warning icon.
     *
     * @param sink doxiasink
     */
    protected void iconWarning( Sink sink )
    {
        icon( sink, "icon_warning_sml" );
    }
    
    /**
     * add an success icon.
     *
     * @param sink doxiasink
     */
    protected 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 error 
     */
    protected void addErrorLine( ConfigurationLineInfo cli, String version, List<String> ignore, String error ) 
    {
        if ( ( ignore != null )
            && ( ignore.contains( cli.getArtifactId() + ':' + version ) || ignore.contains( cli.getArtifactId() ) ) )
        {
            getLog().warn( error );
        }
        else
        {
            getLog().error( error );

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

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