package org.apache.maven.plugin.changes;

/*
 * 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.maven.plugin.issues.Issue;
import org.apache.maven.plugin.issues.IssueManagementSystem;
import org.apache.maven.plugins.changes.model.Action;
import org.apache.maven.plugins.changes.model.Release;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * An adapter that can adapt data models from other issue management system to the data models used in the changes.xml
 * file.
 *
 * @author Dennis Lundberg
 * @version $Id$
 * @since 2.4
 */
public class IssueAdapter
{
    private static final String UNKNOWN_ISSUE_TYPE = "";

    private IssueManagementSystem ims;

    /**
     * Create a new adapter.
     *
     * @param ims The issue management system that has the data that should be adapted
     */
    public IssueAdapter( IssueManagementSystem ims )
    {
        this.ims = ims;
    }

    private Map<String, IssueType> getIssueTypeMap()
    {
        return ims.getIssueTypeMap();
    }

    /**
     * Adapt a <code>List</code> of <code>Issue</code>s to a <code>List</code> of <code>Release</code>s.
     *
     * @param issues The issues
     * @return A list of releases
     */
    public List<Release> getReleases( List<Issue> issues )
    {
        // A Map of releases keyed by fixVersion
        Map<String, Release> releasesMap = new HashMap<String, Release>();

        // Loop through all issues looking for fixVersions
        for ( Issue issue : issues )
        {
            // Do NOT create a release for issues that lack a fixVersion
            if ( issue.getFixVersions() != null )
            {
                for ( String fixVersion : issue.getFixVersions() )
                {
                    // Try to get a matching Release from the map
                    Release release = releasesMap.get( fixVersion );
                    if ( release == null )
                    {
                        // Add a new Release to the Map if it wasn't there
                        release = new Release();
                        release.setVersion( fixVersion );
                        releasesMap.put( fixVersion, release );
                    }

                    // Add this issue as an Action to this release
                    Action action = createAction( issue );
                    release.addAction( action );
                }
            }
        }

        // Extract the releases from the Map to a List
        List<Release> releasesList = new ArrayList<Release>();
        for ( Release release : releasesMap.values() )
        {
            releasesList.add( release );
        }
        return releasesList;
    }

    /**
     * Create an <code>Action</code> from an issue.
     *
     * @param issue The issue to extract the information from
     * @return An <code>Action</code>
     */
    public Action createAction( Issue issue )
    {
        Action action = new Action();

        // @todo We need to add something like issue.getPresentationIdentifier() to be able to support other IMSes
        // beside JIRA
        action.setIssue( issue.getKey() );

        // Try to map the IMS-specific issue type to one that is used in a changes.xml file
        IssueType type;
        if ( getIssueTypeMap().containsKey( issue.getType() ) )
        {
            type = getIssueTypeMap().get( issue.getType() );
            action.setType( type.modelRepresentation() );
        }
        else
        {
            action.setType( UNKNOWN_ISSUE_TYPE );
        }

        action.setDev( issue.getAssignee() );

        action.setDueTo( issue.getReporter() == null ? "" : issue.getReporter() );

        action.setAction( issue.getSummary() );
        return action;
    }
}
