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.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugins.issues.Issue;
import org.codehaus.plexus.util.IOUtil;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.helpers.DefaultHandler;

/**
 * XML parser that extracts <code>Issue</code>s from JIRA. This works on an XML file downloaded from JIRA and creates a
 * <code>List</code> of issues that is exposed to the user of the class.
 * 
 * @version $Id$
 */
public class JiraXML
    extends DefaultHandler
{
    private final List<Issue> issueList;

    private final StringBuilder currentElement = new StringBuilder( 1024 );

    private String currentParent = "";

    private final String datePattern;

    private Issue issue;

    private String jiraVersion = null;

    private final Log log;

    private SimpleDateFormat sdf;

    /**
     * @param log not null.
     * @param datePattern may be null.
     * @since 2.4
     */
    public JiraXML( Log log, String datePattern )
    {
        this.log = log;
        this.datePattern = datePattern;

        if ( datePattern == null )
        {
            sdf = null;
        }
        else
        {
            // @todo Do we need to be able to configure the locale of the JIRA server as well?
            sdf = new SimpleDateFormat( datePattern, Locale.ENGLISH );
        }

        this.issueList = new ArrayList<>( 16 );
    }

    /**
     * Parse the given xml file. The list of issues can then be retrieved with {@link #getIssueList()}.
     * 
     * @param xmlPath the file to pares.
     * @throws MojoExecutionException in case of errors.
     * @since 2.4
     */
    public void parseXML( File xmlPath )
        throws MojoExecutionException
    {
        InputStream xmlStream = null;
        try
        {
            xmlStream = new FileInputStream( xmlPath );
            InputSource inputSource = new InputSource( xmlStream );
            parse( inputSource );
        }
        catch ( FileNotFoundException e )
        {
            throw new MojoExecutionException( "Failed to open JIRA XML file " + xmlPath, e );
        }
        finally
        {
            IOUtil.close( xmlStream );
        }
    }

    void parse( InputSource xmlSource )
        throws MojoExecutionException
    {
        try
        {
            SAXParserFactory factory = SAXParserFactory.newInstance();
            SAXParser saxParser = factory.newSAXParser();

            saxParser.parse( xmlSource, this );
        }
        catch ( Throwable t )
        {
            throw new MojoExecutionException( "Failed to parse JIRA XML.", t );
        }
    }

    public void startElement( String namespaceURI, String sName, String qName, Attributes attrs )
    {
        switch ( qName )
        {
            case "item":
                issue = new Issue();

                currentParent = "item";
                break;
            case "key":
                String id = attrs.getValue( "id" );
                if ( id != null )
                {
                    issue.setId( id.trim() );
                }
                break;
            case "build-info":
                currentParent = "build-info";
                break;
            default:
                // none
        }
    }

    public void endElement( String namespaceURI, String sName, String qName )
    {
        if ( qName.equals( "item" ) )
        {
            issueList.add( issue );

            currentParent = "";
        }
        else if ( qName.equals( "key" ) )
        {
            issue.setKey( currentElement.toString().trim() );
        }
        else if ( qName.equals( "summary" ) )
        {
            issue.setSummary( currentElement.toString().trim() );
        }
        else if ( qName.equals( "type" ) )
        {
            issue.setType( currentElement.toString().trim() );
        }
        else if ( qName.equals( "link" ) && currentParent.equals( "item" ) )
        {
            issue.setLink( currentElement.toString().trim() );
        }
        else if ( qName.equals( "priority" ) )
        {
            issue.setPriority( currentElement.toString().trim() );
        }
        else if ( qName.equals( "status" ) )
        {
            issue.setStatus( currentElement.toString().trim() );
        }
        else if ( qName.equals( "resolution" ) )
        {
            issue.setResolution( currentElement.toString().trim() );
        }
        else if ( qName.equals( "assignee" ) )
        {
            issue.setAssignee( currentElement.toString().trim() );
        }
        else if ( qName.equals( "reporter" ) )
        {
            issue.setReporter( currentElement.toString().trim() );
        }
        else if ( qName.equals( "version" ) && currentParent.equals( "item" ) )
        {
            issue.setVersion( currentElement.toString().trim() );
        }
        else if ( qName.equals( "version" ) && currentParent.equals( "build-info" ) )
        {
            jiraVersion = currentElement.toString().trim();
        }
        else if ( qName.equals( "fixVersion" ) )
        {
            issue.addFixVersion( currentElement.toString().trim() );
        }
        else if ( qName.equals( "component" ) )
        {
            issue.addComponent( currentElement.toString().trim() );
        }
        else if ( qName.equals( "comment" ) )
        {
            issue.addComment( currentElement.toString().trim() );
        }
        else if ( qName.equals( "title" ) && currentParent.equals( "item" ) )
        {
            issue.setTitle( currentElement.toString().trim() );
        }
        else if ( qName.equals( "created" ) && currentParent.equals( "item" ) && sdf != null )
        {
            try
            {
                issue.setCreated( sdf.parse( currentElement.toString().trim() ) );
            }
            catch ( ParseException e )
            {
                log.warn( "Element \"Created\". " + e.getMessage() + ". Using the pattern \"" + datePattern + "\"" );
            }
        }
        else if ( qName.equals( "updated" ) && currentParent.equals( "item" ) && sdf != null )
        {
            try
            {
                issue.setUpdated( sdf.parse( currentElement.toString().trim() ) );
            }
            catch ( ParseException e )
            {
                log.warn( "Element \"Updated\". " + e.getMessage() + ". Using the pattern \"" + datePattern + "\"" );
            }
        }

        currentElement.setLength( 0 );
    }

    public void characters( char[] buf, int offset, int len )
    {
        currentElement.append( buf, offset, len );
    }

    public List<Issue> getIssueList()
    {
        return Collections.unmodifiableList( this.issueList );
    }

    public String getJiraVersion()
    {
        return jiraVersion;
    }
}
