package org.apache.maven.dist.tools.masterjobs;

/*
 * 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.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.maven.dist.tools.JsoupRetry;
import org.apache.maven.doxia.sink.Sink;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.reporting.AbstractMavenReport;
import org.apache.maven.reporting.MavenReportException;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

/**
 * Generate report with build status of the Jenkins job for the master branch of every Git repository in
 * <a href="https://ci-builds.apache.org/job/Maven/job/maven-box/">{@code maven-box} Apache Hosted Git Folder job</a>.
 *
 * @author Robert Scholte
 */
@Mojo( name = "list-master-jobs", requiresProject = false )
public class ListMasterJobsMojo extends AbstractMavenReport
{
    private String gitboxUrl = "https://gitbox.apache.org/repos/asf";
    private String mavenboxJobsBaseUrl = "https://ci-builds.apache.org/job/Maven/job/maven-box/";
    
    private Collection<String> excluded = Arrays.asList( "maven-integration-testing", // runs with Maven core job
                                                         "maven-jenkins-env",
                                                         "maven-jenkins-lib",
                                                         "maven-sources",
                                                         "maven-studies" );

    @Override
    public String getOutputName()
    {
        return "dist-tool-master-jobs";
    }

    @Override
    public String getName( Locale locale )
    {
        return "Dist Tool> List Master Jobs";
    }

    @Override
    public String getDescription( Locale locale )
    {
        return "Shows the status of Jenkins job for the master branch of every Git repository on one page";
    }

    @Override
    protected void executeReport( Locale locale )
        throws MavenReportException
    {
        Collection<String> repositoryNames;
        try
        {
            repositoryNames = repositoryNames();
        }
        catch ( IOException e )
        {
            throw new MavenReportException( "Failed to extract repositorynames from Gitbox", e );
        }
        
        List<Result> repoStatus = new ArrayList<>( repositoryNames.size() );
        
        Collection<String> included = repositoryNames.stream()
                                                     .filter( s -> !excluded.contains( s ) )
                                                     .collect( Collectors.toList() );
        
        for ( String repository : included )
        {
            final String repositoryJobUrl = mavenboxJobsBaseUrl + repository;

            try
            {
                Document doc = JsoupRetry.get( repositoryJobUrl );
                
                Result result = new Result( repository, repositoryJobUrl );
                
                Element masterRow = doc.getElementById( "job_master" );
                if ( masterRow == null )
                {
                    getLog().warn( mavenboxJobsBaseUrl + repository + " is missing id job_master" );
                    continue;
                }
                else if ( masterRow.hasClass( "job-status-red" ) || masterRow.hasClass( "job-status-red-anime" ) )
                {
                    result.setStatus( "FAILURE" );
                }
                else if ( masterRow.hasClass( "job-status-yellow" ) || masterRow.hasClass( "job-status-yellow-anime" ) )
                {
                    result.setStatus( "UNSTABLE" );
                }
                else if ( masterRow.hasClass( "job-status-blue" ) || masterRow.hasClass( "job-status-blue-anime" ) )
                {
                    result.setStatus( "SUCCESS" );
                }
                else
                {
                    result.setStatus( "UNKNOWN" );
                }
                result.setIcon( masterRow.select( "img" ).first().outerHtml() );
                
                repoStatus.add( result );
            }
            catch ( IOException e )
            {
                getLog().warn( "Failed to read status for " + repository + " Jenkins job " + repositoryJobUrl  );
            }
        }
        
        generateReport( repoStatus );
    }
    
    private void generateReport( List<Result> repoStatus )
    {
        Sink sink = getSink();
        
        sink.head();
        sink.title();
        sink.text( "List Master Jobs" );
        sink.title_();
        sink.head_();
        
        sink.body();
        sink.text( "Jenkins jobs for master branch sorted by status of last build:" );
        sink.list();
        
        Map<String, List<Result>> groupedResults = repoStatus.stream()
                                                             .collect( Collectors.groupingBy( Result::getStatus ) );
        
        groupedResults.entrySet()
                      .stream()
                      .sorted( Map.Entry.comparingByKey( resultComparator() ) )
                      .forEach( e -> 
            {
                sink.listItem();
                int size = e.getValue().size();
                sink.text( size + " job" + ( size > 1 ? "s" : "" ) + " with status " + e.getKey() + ":" );
                sink.list();
                e.getValue().forEach( r -> 
                {
                    sink.listItem();
                    sink.rawText( r.getIcon() );
                    sink.link( r.getBuildUrl() );
                    sink.rawText( r.getRepositoryName() );
                    sink.link_();
                    sink.listItem_();
                } );
                sink.list_();
                
                sink.listItem_();
            } );
        
        sink.list_();
        sink.body_();
    }
    
    private Comparator<String> resultComparator()
    {
        final List<String> orderedStatus = Arrays.asList( "FAILURE", "UNSTABLE", "UNKNOWN", "SUCCESS" );
        return ( l, r ) -> 
            {
                return Integer.compare( orderedStatus.indexOf( l ), orderedStatus.indexOf( r ) );
            };
    }

    /**
     * Extract Git repository names for Apache Maven from
     * <a href="https://gitbox.apache.org/repos/asf">Gitbox main page</a>.
     *
     * @return the list of repository names (without ".git")
     * @throws IOException problem with reading repository index
     */
    protected Collection<String> repositoryNames()
        throws IOException
    {
        List<String> names = new ArrayList<>( 100 );
        Document doc = JsoupRetry.get( gitboxUrl );
        // find Apache Maven table
        Element apacheMavenTable = doc.getElementsMatchingText( "^Apache Maven$" ).parents().get( 0 );

        Elements gitRepo = apacheMavenTable.select( "tbody tr" ).not( "tr.disabled" ).select( "td:first-child a" );

        for ( Element element : gitRepo )
        {
            names.add( element.text().split( "\\.git" )[0] );
        }

        return names;
    }
}
