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.maven.plugin.logging.Log;

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

/**
 * JIRA 3.x way of constructing a search query based on URL parameters.
 * 
 * @author ton.swieb@finalist.com
 * @version $Id$
 * @since 2.8
 */
public class ParameterQueryBuilder
    implements JiraQueryBuilder
{
    private String filter = "";
    /** Log for debug output. */
    private Log log;
    private StringBuilder query = new StringBuilder();

    /** Mapping containing all allowed JIRA priority values. */
    private final Map<String, String> priorityMap = new HashMap<String, String>( 8 );
    /** Mapping containing all allowed JIRA resolution values. */
    private final Map<String, String> resolutionMap = new HashMap<String, String>( 8 );
    /** Mapping containing all allowed JIRA status values. */
    private final Map<String, String> statusMap = new HashMap<String, String>( 8 );
    /** Mapping containing all allowed JIRA type values. */
    private final Map<String, String> typeMap = new HashMap<String, String>( 8 );

    public ParameterQueryBuilder( Log log )
    {
        this.log = log;

        priorityMap.put( "Blocker", "1" );
        priorityMap.put( "Critical", "2" );
        priorityMap.put( "Major", "3" );
        priorityMap.put( "Minor", "4" );
        priorityMap.put( "Trivial", "5" );

        resolutionMap.put( "Unresolved", "-1" );
        resolutionMap.put( "Fixed", "1" );
        resolutionMap.put( "Won't Fix", "2" );
        resolutionMap.put( "Duplicate", "3" );
        resolutionMap.put( "Incomplete", "4" );
        resolutionMap.put( "Cannot Reproduce", "5" );

        statusMap.put( "Open", "1" );
        statusMap.put( "In Progress", "3" );
        statusMap.put( "Reopened", "4" );
        statusMap.put( "Resolved", "5" );
        statusMap.put( "Closed", "6" );

        typeMap.put( "Bug", "1" );
        typeMap.put( "New Feature", "2" );
        typeMap.put( "Task", "3" );
        typeMap.put( "Improvement", "4" );
        typeMap.put( "Wish", "5" );
        typeMap.put( "Test", "6" );
        typeMap.put( "Sub-task", "7" );
    }

    public String build()
    {
        // If the user has defined a filter - use that
        if ( ( this.filter != null ) && ( this.filter.length() > 0 ) )
        {
            return this.filter;
        }
        else
        {
            return query.toString();
        }
    }

    public JiraQueryBuilder components( String components )
    {
        // add components
        if ( components != null )
        {
            String[] componentsArr = components.split( "," );

            for ( String component : componentsArr )
            {
                component = component.trim();
                if ( component.length() > 0 )
                {
                    query.append( "&component=" ).append( component );
                }
            }
        }
        return this;
    }

    public JiraQueryBuilder components( List<String> components )
    {
        // add components
        if ( components != null )
        {
            for ( String component : components )
            {
                component = component.trim();
                if ( component.length() > 0 )
                {
                    query.append( "&component=" ).append( component );
                }
            }
        }
        return this;
    }

    public JiraQueryBuilder filter( String filter )
    {
        this.filter = filter;
        return this;
    }

    /**
     * This method has no effect in this implementation.
     */
    public JiraQueryBuilder fixVersion( String fixVersion )
    {
        return this;
    }

    public JiraQueryBuilder fixVersionIds( String fixVersionIds )
    {
        // add fix versions
        if ( fixVersionIds != null )
        {
            String[] fixVersions = fixVersionIds.split( "," );

            for ( String fixVersion : fixVersions )
            {
                if ( fixVersion.length() > 0 )
                {
                    query.append( "&fixfor=" ).append( fixVersion.trim() );
                }
            }
        }
        return this;
    }

    public JiraQueryBuilder fixVersionIds( List<String> fixVersionIds )
    {
        throw new RuntimeException( "fixVersionIds(List) not supported for very old parameter queries." );
    }

    public Log getLog()
    {
        return log;
    }

    public JiraQueryBuilder priorityIds( String priorityIds )
    {
        // get the Priority Ids
        if ( priorityIds != null )
        {
            String[] prios = priorityIds.split( "," );

            for ( String prio : prios )
            {
                prio = prio.trim();
                String priorityParam = priorityMap.get( prio );

                if ( priorityParam != null )
                {
                    query.append( "&priorityIds=" ).append( priorityParam );
                }
            }
        }
        return this;
    }

    public JiraQueryBuilder priorityIds( List<String> priorityIds )
    {
        throw new RuntimeException( "priorityIds(List) not supported for old parameter queries." );
    }

    /**
     * This method has no effect in this implementation.
     */
    public JiraQueryBuilder project( String project )
    {
        return this;
    }

    public JiraQueryBuilder resolutionIds( String resolutionIds )
    {
        // get the Resolution Ids
        if ( resolutionIds != null )
        {
            String[] resos = resolutionIds.split( "," );

            for ( String reso : resos )
            {
                reso = reso.trim();
                String resoParam = resolutionMap.get( reso );

                if ( resoParam != null )
                {
                    query.append( "&resolutionIds=" ).append( resoParam );
                }
            }
        }
        return this;
    }

    public JiraQueryBuilder resolutionIds( List<String> resolutionIds )
    {
        throw new RuntimeException( "resolutionIds(List) not supported for old ParameterQueryBuilder" );
    }

    public JiraQueryBuilder sortColumnNames( String sortColumnNames )
    {
        // get the Sort order
        int validSortColumnNames = 0;
        if ( sortColumnNames != null )
        {
            String[] sortColumnNamesArray = sortColumnNames.split( "," );
            // N.B. Add in reverse order (it's the way JIRA 3 likes it!!)
            for ( int i = sortColumnNamesArray.length - 1; i >= 0; i-- )
            {
                String lowerColumnName = sortColumnNamesArray[i].trim().toLowerCase( Locale.ENGLISH );
                boolean descending = false;
                String fieldName = null;
                if ( lowerColumnName.endsWith( "desc" ) )
                {
                    descending = true;
                    lowerColumnName = lowerColumnName.substring( 0, lowerColumnName.length() - 4 ).trim();
                }
                else if ( lowerColumnName.endsWith( "asc" ) )
                {
                    descending = false;
                    lowerColumnName = lowerColumnName.substring( 0, lowerColumnName.length() - 3 ).trim();
                }

                if ( "key".equals( lowerColumnName ) )
                {
                    fieldName = "issuekey";
                }
                else if ( "summary".equals( lowerColumnName ) )
                {
                    fieldName = lowerColumnName;
                }
                else if ( "status".equals( lowerColumnName ) )
                {
                    fieldName = lowerColumnName;
                }
                else if ( "resolution".equals( lowerColumnName ) )
                {
                    fieldName = lowerColumnName;
                }
                else if ( "assignee".equals( lowerColumnName ) )
                {
                    fieldName = lowerColumnName;
                }
                else if ( "reporter".equals( lowerColumnName ) )
                {
                    fieldName = lowerColumnName;
                }
                else if ( "type".equals( lowerColumnName ) )
                {
                    fieldName = "issuetype";
                }
                else if ( "priority".equals( lowerColumnName ) )
                {
                    fieldName = lowerColumnName;
                }
                else if ( "version".equals( lowerColumnName ) )
                {
                    fieldName = "versions";
                }
                else if ( "fix version".equals( lowerColumnName ) )
                {
                    fieldName = "fixVersions";
                }
                else if ( "component".equals( lowerColumnName ) )
                {
                    fieldName = "components";
                }
                else if ( "created".equals( lowerColumnName ) )
                {
                    fieldName = lowerColumnName;
                }
                else if ( "updated".equals( lowerColumnName ) )
                {
                    fieldName = lowerColumnName;
                }
                if ( fieldName != null )
                {
                    query.append( "&sorter/field=" );
                    query.append( fieldName );
                    query.append( "&sorter/order=" );
                    query.append( descending ? "DESC" : "ASC" );
                    validSortColumnNames++;
                }
                else
                {
                    // Error in the configuration
                    getLog().error(
                        "maven-changes-plugin: The configured value '" + lowerColumnName
                            + "' for sortColumnNames is not correct." );
                }
            }
            if ( validSortColumnNames == 0 )
            {
                // Error in the configuration
                getLog().error(
                    "maven-changes-plugin: None of the configured sortColumnNames '" + sortColumnNames + "' are correct." );
            }
        }
        return this;
    }

    public JiraQueryBuilder statusIds( String statusIds )
    {
        // get the Status Ids
        if ( statusIds != null )
        {
            String[] stats = statusIds.split( "," );
            for ( String stat : stats )
            {
                stat = stat.trim();
                String statusParam = statusMap.get( stat );

                if ( statusParam != null )
                {
                    query.append( "&statusIds=" ).append( statusParam );
                }
                else
                {
                    // if it's numeric we can handle it too.
                    try
                    {
                        Integer.parseInt( stat );
                        query.append( "&statusIds=" ).append( stat );
                    }
                    catch ( NumberFormatException nfe )
                    {
                        getLog().error( "maven-changes-plugin: invalid statusId " + stat );
                    }
                }
            }
        }
        return this;
    }

    public JiraQueryBuilder statusIds( List<String> statusIds )
    {
        throw new RuntimeException( "statusIds(List) not supported for old parameter queries." );
    }

    public JiraQueryBuilder typeIds( String typeIds )
    {
        // get the Type Ids
        if ( typeIds != null )
        {
            String[] types = typeIds.split( "," );

            for ( String type : types )
            {
                String typeParam = typeMap.get( type.trim() );

                if ( typeParam != null )
                {
                    query.append( "&type=" ).append( typeParam );
                }
            }
        }
        return this;
    }

    public JiraQueryBuilder typeIds( List<String> typeIds )
    {
        throw new RuntimeException( "typeIds(List) not supported for old ParameterQueryBuilder" );
    }
}
