package org.apache.maven.plugins.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 java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;

import org.apache.commons.lang.StringUtils;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.plugins.changes.AbstractChangesReport;
import org.apache.maven.plugins.changes.ProjectUtils;
import org.apache.maven.plugins.issues.Issue;
import org.apache.maven.plugins.issues.IssueUtils;
import org.apache.maven.plugins.issues.IssuesReportGenerator;
import org.apache.maven.plugins.issues.IssuesReportHelper;
import org.apache.maven.reporting.MavenReportException;
import org.apache.maven.settings.Server;
import org.apache.maven.settings.Settings;

/**
 * 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<>( 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
    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()
    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
    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
    private String jiraPassword;

    /**
     * Defines the JIRA username for authentication into a private JIRA installation.
     */
    @Parameter
    private String jiraUser;

    /**
     * The settings.xml server id to be used for authentication into a private JIRA installation.
     *
     * @since 3.0.0
     */
    @Parameter( property = "changes.jiraServerId" )
    private String jiraServerId;

    /**
     * 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
    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
    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
    private String versionPrefix;

    /**
     * Defines the http password for basic authentication into the JIRA webserver.
     */
    @Parameter
    private String webPassword;

    /**
     * Defines the http user for basic authentication into the JIRA webserver.
     */
    @Parameter
    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;
        }
        String message = ProjectUtils.validateIssueManagement( project, "JIRA", "JIRA Report" );
        if ( message != null )
        {
            getLog().warn( message );
        }
        return message == null;
    }

    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 );

        if ( jiraServerId != null )
        {
            final Server server = mavenSession.getSettings().getServer( jiraServerId );
            issueDownloader.setJiraUser( server.getUsername() );
            issueDownloader.setJiraPassword( server.getPassword() );
        }
        else
        {
            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;
    }
}
