package org.apache.maven.plugin.jira;

/*
 * 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.lang.StringUtils;
import org.apache.maven.plugin.changes.AbstractChangesReport;
import org.apache.maven.plugin.changes.ProjectUtils;
import org.apache.maven.plugin.issues.Issue;
import org.apache.maven.plugin.issues.IssueUtils;
import org.apache.maven.plugin.issues.IssuesReportGenerator;
import org.apache.maven.plugin.issues.IssuesReportHelper;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.settings.Settings;

import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

/**
 * Goal which downloads issues from the Issue Tracking System and generates a report.
 *
 * @author <a href="mailto:jruiz@exist.com">Johnny R. Ruiz III</a>
 * @version $Id$
 */
@Mojo( name = "jira-report", threadSafe = true )
public class JiraMojo
    extends AbstractChangesReport
{
    /**
     * Valid JIRA columns.
     */
    private static final Map<String, Integer> JIRA_COLUMNS = new HashMap<String, Integer>( 16 );

    static
    {
        JIRA_COLUMNS.put( "Assignee", IssuesReportHelper.COLUMN_ASSIGNEE );
        JIRA_COLUMNS.put( "Component", IssuesReportHelper.COLUMN_COMPONENT );
        JIRA_COLUMNS.put( "Created", IssuesReportHelper.COLUMN_CREATED );
        JIRA_COLUMNS.put( "Fix Version", IssuesReportHelper.COLUMN_FIX_VERSION );
        JIRA_COLUMNS.put( "Id", IssuesReportHelper.COLUMN_ID );
        JIRA_COLUMNS.put( "Key", IssuesReportHelper.COLUMN_KEY );
        JIRA_COLUMNS.put( "Priority", IssuesReportHelper.COLUMN_PRIORITY );
        JIRA_COLUMNS.put( "Reporter", IssuesReportHelper.COLUMN_REPORTER );
        JIRA_COLUMNS.put( "Resolution", IssuesReportHelper.COLUMN_RESOLUTION );
        JIRA_COLUMNS.put( "Status", IssuesReportHelper.COLUMN_STATUS );
        JIRA_COLUMNS.put( "Summary", IssuesReportHelper.COLUMN_SUMMARY );
        JIRA_COLUMNS.put( "Type", IssuesReportHelper.COLUMN_TYPE );
        JIRA_COLUMNS.put( "Updated", IssuesReportHelper.COLUMN_UPDATED );
        JIRA_COLUMNS.put( "Version", IssuesReportHelper.COLUMN_VERSION );
    }

    /**
     * Sets the names of the columns that you want in the report. The columns will appear in the report in the same
     * order as you specify them here. Multiple values can be separated by commas.
     * <p>
     * Valid columns are: <code>Assignee</code>, <code>Component</code>, <code>Created</code>, <code>Fix Version</code>,
     * <code>Id</code>, <code>Key</code>, <code>Priority</code>, <code>Reporter</code>, <code>Resolution</code>,
     * <code>Status</code>, <code>Summary</code>, <code>Type</code>, <code>Updated</code> and <code>Version</code>.
     * </p>
     *
     * @since 2.0
     */
    @Parameter( defaultValue = "Key,Summary,Status,Resolution,Assignee" )
    private String columnNames;

    /**
     * Use the JIRA query language instead of the JIRA query based on HTTP parameters. From JIRA 5.1 and up only JQL is
     * supported. JIRA 4.4 supports both JQL and URL parameter based queries. From 5.1.1 this is obsolete, since REST
     * queries only use JQL.
     *
     * @since 2.8
     */
    @Parameter( property = "changes.useJql", defaultValue = "false" )
    private boolean useJql;

    /**
     * Since JIRA 5.1.1, it is no longer possible to construct a URL that downloads RSS. Meanwhile JIRA added a REST API
     * in 4.2. By default, this plugin uses the REST API if available. Setting this parameter to true forces it to
     * attempt to use RSS.
     *
     * @since 2.9
     */
    @Parameter( defaultValue = "false" )
    private boolean forceRss;

    /**
     * Sets the component(s) that you want to limit your report to include. Multiple values can be separated by commas
     * (such as 10011,10012). If this is set to empty - that means all components will be included.
     */
    @Parameter( defaultValue = "" )
    private String component;

    /**
     * Defines the filter parameters to restrict which issues are retrieved from JIRA. The filter parameter uses the
     * same format of url parameters that is used in a JIRA search.
     */
    @Parameter( defaultValue = "" )
    private String filter;

    /**
     * Sets the fix version id(s) that you want to limit your report to include. These are JIRA's internal version ids,
     * <b>NOT</b> the human readable display ones. Multiple fix versions can be separated by commas. If this is set to
     * empty - that means all fix versions will be included.
     *
     * @since 2.0
     */
    @Parameter( defaultValue = "" )
    private String fixVersionIds;

    /**
     * The pattern used by dates in the JIRA XML-file. This is used to parse the Created and Updated fields.
     *
     * @since 2.4
     */
    @Parameter( defaultValue = "EEE, d MMM yyyy HH:mm:ss Z" )
    private String jiraDatePattern;

    /**
     * Defines the JIRA password for authentication into a private JIRA installation.
     */
    @Parameter( defaultValue = "" )
    private String jiraPassword;

    /**
     * Defines the JIRA username for authentication into a private JIRA installation.
     */
    @Parameter( defaultValue = "" )
    private String jiraUser;

    /**
     * Path to the JIRA XML file, which will be parsed.
     */
    @Parameter( defaultValue = "${project.build.directory}/jira-results.xml", required = true, readonly = true )
    private File jiraXmlPath;

    /**
     * Maximum number of entries to be fetched from JIRA.
     */
    @Parameter( defaultValue = "100" )
    private int maxEntries;

    /**
     * If you only want to show issues for the current version in the report. The current version being used is
     * <code>${project.version}</code> minus any "-SNAPSHOT" suffix.
     *
     * @since 2.0
     */
    @Parameter( defaultValue = "false" )
    private boolean onlyCurrentVersion;

    /**
     * Sets the priority(s) that you want to limit your report to include. Valid statuses are <code>Blocker</code>,
     * <code>Critical</code>, <code>Major</code>, <code>Minor</code> and <code>Trivial</code>. Multiple values can be
     * separated by commas. If this is set to empty - that means all priorities will be included.
     */
    @Parameter( defaultValue = "" )
    private String priorityIds;

    /**
     * Sets the resolution(s) that you want to fetch from JIRA. Valid resolutions are: <code>Unresolved</code>,
     * <code>Fixed</code>, <code>Won't Fix</code>, <code>Duplicate</code>, <code>Incomplete</code> and
     * <code>Cannot Reproduce</code>. Multiple values can be separated by commas.
     * <p>
     * <b>Note:</b> In versions 2.0-beta-3 and earlier this parameter had no default value.
     * </p>
     */
    @Parameter( defaultValue = "Fixed" )
    private String resolutionIds;

    /**
     * Settings XML configuration.
     */
    @Parameter( defaultValue = "${settings}", readonly = true, required = true )
    private Settings settings;

    /**
     * If set to <code>true</code>, then the JIRA report will not be generated.
     * 
     * @since 2.8
     */
    @Parameter( property = "changes.jira.skip", defaultValue = "false" )
    private boolean skip;

    /**
     * Sets the column names that you want to sort the report by. Add <code>DESC</code> following the column name to
     * specify <i>descending</i> sequence. For example <code>Fix Version DESC, Type</code> sorts first by the Fix
     * Version in descending order and then by Type in ascending order. By default sorting is done in ascending order,
     * but is possible to specify <code>ASC</code> for consistency. The previous example would then become
     * <code>Fix Version DESC, Type ASC</code>.
     * <p>
     * Valid columns are: <code>Assignee</code>, <code>Component</code>, <code>Created</code>, <code>Fix Version</code>,
     * <code>Id</code>, <code>Key</code>, <code>Priority</code>, <code>Reporter</code>, <code>Resolution</code>,
     * <code>Status</code>, <code>Summary</code>, <code>Type</code>, <code>Updated</code> and <code>Version</code>.
     * </p>
     * <p>
     * <strong>Note:</strong> If you are using JIRA 4 you need to put your sort column names in the reverse order. The
     * handling of this changed between JIRA 3 and JIRA 4. The current default value is suitable for JIRA 3. This may
     * change in the future, so please configure your sort column names in an order that works for your own JIRA
     * version. If you use JQL, by setting the <code>useJql</code> parameter to <code>true</code>, then the order of the
     * fields are in normal order again. Starting with JIRA 5.1 you have to use JQL.
     * </p>
     *
     * @since 2.0
     */
    @Parameter( defaultValue = "Priority DESC, Created DESC" )
    private String sortColumnNames;

    /**
     * Sets the status(es) that you want to fetch from JIRA. Valid statuses are: <code>Open</code>,
     * <code>In Progress</code>, <code>Reopened</code>, <code>Resolved</code> and <code>Closed</code>. Multiple values
     * can be separated by commas.
     * <p>
     * If your installation of JIRA uses custom status IDs, you can reference them here by their numeric values. You can
     * obtain them on the Statuses page (in 4.0.2 it's under Administration > Issue Settings > Statuses) - just hover
     * over the Edit link for the status you want and you'll see something like &lt;your JIRA
     * URL&gt;/secure/admin/EditStatus!default.jspa?id=12345; in this case the value is 12345.
     * </p>
     * <p>
     * <b>Note:</b> In versions 2.0-beta-3 and earlier this parameter had no default value.
     * </p>
     */
    @Parameter( defaultValue = "Closed" )
    private String statusIds;

    /**
     * Sets the types(s) that you want to limit your report to include. Valid types are: <code>Bug</code>,
     * <code>New Feature</code>, <code>Task</code>, <code>Improvement</code>, <code>Wish</code>, <code>Test</code> and
     * <code>Sub-task</code>. Multiple values can be separated by commas. If this is set to empty - that means all types
     * will be included.
     *
     * @since 2.0
     */
    @Parameter( defaultValue = "" )
    private String typeIds;

    /**
     * The prefix used when naming versions in JIRA.
     * <p>
     * If you have a project in JIRA with several components that have different release cycles, it is an often used
     * pattern to prefix the version with the name of the component, e.g. maven-filtering-1.0 etc. To fetch issues from
     * JIRA for a release of the "maven-filtering" component you would need to set this parameter to "maven-filtering-".
     * </p>
     *
     * @since 2.4
     */
    @Parameter( defaultValue = "" )
    private String versionPrefix;

    /**
     * Defines the http password for basic authentication into the JIRA webserver.
     */
    @Parameter( defaultValue = "" )
    private String webPassword;

    /**
     * Defines the http user for basic authentication into the JIRA webserver.
     */
    @Parameter( defaultValue = "" )
    private String webUser;

    /*
     * Used for tests.
     */
    private AbstractJiraDownloader mockDownloader;

    /* --------------------------------------------------------------------- */
    /* Public methods */
    /* --------------------------------------------------------------------- */

    /**
     * @see org.apache.maven.reporting.AbstractMavenReport#canGenerateReport()
     */
    public boolean canGenerateReport()
    {
        // Run only at the execution root
        if ( runOnlyAtExecutionRoot && !isThisTheExecutionRoot() )
        {
            getLog().info( "Skipping the JIRA Report in this project because it's not the Execution Root" );
            return false;
        }
        if ( skip )
        {
            return false;
        }
        if ( mockDownloader != null )
        {
            return true;
        }
        return ProjectUtils.validateIfIssueManagementComplete( project, "JIRA", "JIRA Report", getLog() );
    }

    public void executeReport( Locale locale )
        throws MavenReportException
    {
        // Validate parameters
        List<Integer> columnIds = IssuesReportHelper.getColumnIds( columnNames, JIRA_COLUMNS );
        if ( columnIds.isEmpty() )
        {
            // This can happen if the user has configured column names and they are all invalid
            throw new MavenReportException( "maven-changes-plugin: None of the configured columnNames '" + columnNames
                + "' are valid." );
        }

        try
        {
            // Download issues
            AbstractJiraDownloader issueDownloader;
            if ( mockDownloader != null )
            {
                issueDownloader = mockDownloader;
            }
            else
            {
                AdaptiveJiraDownloader downloader = new AdaptiveJiraDownloader();
                downloader.setForceClassic( forceRss );
                issueDownloader = downloader;
            }
            configureIssueDownloader( issueDownloader );
            issueDownloader.doExecute();

            List<Issue> issueList = issueDownloader.getIssueList();

            if ( StringUtils.isNotEmpty( versionPrefix ) )
            {
                int originalNumberOfIssues = issueList.size();
                issueList = IssueUtils.filterIssuesWithVersionPrefix( issueList, versionPrefix );
                getLog().debug( "Filtered out " + issueList.size() + " issues of " + originalNumberOfIssues
                    + " that matched the versionPrefix '" + versionPrefix + "'." );
            }

            if ( onlyCurrentVersion )
            {
                String version = ( versionPrefix == null ? "" : versionPrefix ) + project.getVersion();
                issueList = IssueUtils.getIssuesForVersion( issueList, version );
                getLog().info( "The JIRA Report will contain issues only for the current version." );
            }

            // Generate the report
            IssuesReportGenerator report = new IssuesReportGenerator( IssuesReportHelper.toIntArray( columnIds ) );

            if ( issueList.isEmpty() )
            {
                report.doGenerateEmptyReport( getBundle( locale ), getSink() );
            }
            else
            {
                report.doGenerateReport( getBundle( locale ), getSink(), issueList );
            }
        }
        catch ( Exception e )
        {
            getLog().warn( e );
        }
    }

    public String getDescription( Locale locale )
    {
        return getBundle( locale ).getString( "report.issues.description" );
    }

    public String getName( Locale locale )
    {
        return getBundle( locale ).getString( "report.issues.name" );
    }

    public String getOutputName()
    {
        return "jira-report";
    }

    /* --------------------------------------------------------------------- */
    /* Private methods */
    /* --------------------------------------------------------------------- */

    private ResourceBundle getBundle( Locale locale )
    {
        return ResourceBundle.getBundle( "jira-report", locale, this.getClass().getClassLoader() );
    }

    private void configureIssueDownloader( AbstractJiraDownloader issueDownloader )
    {
        issueDownloader.setLog( getLog() );

        issueDownloader.setMavenProject( project );

        issueDownloader.setOutput( jiraXmlPath );

        issueDownloader.setNbEntries( maxEntries );

        issueDownloader.setComponent( component );

        issueDownloader.setFixVersionIds( fixVersionIds );

        issueDownloader.setStatusIds( statusIds );

        issueDownloader.setResolutionIds( resolutionIds );

        issueDownloader.setPriorityIds( priorityIds );

        issueDownloader.setSortColumnNames( sortColumnNames );

        issueDownloader.setFilter( filter );

        issueDownloader.setJiraDatePattern( jiraDatePattern );

        issueDownloader.setJiraUser( jiraUser );

        issueDownloader.setJiraPassword( jiraPassword );

        issueDownloader.setTypeIds( typeIds );

        issueDownloader.setWebUser( webUser );

        issueDownloader.setWebPassword( webPassword );

        issueDownloader.setSettings( settings );

        issueDownloader.setUseJql( useJql );

        issueDownloader.setOnlyCurrentVersion( onlyCurrentVersion );

        issueDownloader.setVersionPrefix( versionPrefix );
    }

    public void setMockDownloader( AbstractJiraDownloader mockDownloader )
    {
        this.mockDownloader = mockDownloader;
    }

    public AbstractJiraDownloader getMockDownloader()
    {
        return mockDownloader;
    }
}
