package org.apache.maven.scm;

/*
 * 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.Serializable;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import org.apache.maven.scm.provider.ScmProviderRepository;
import org.apache.maven.scm.util.FilenameUtils;
import org.apache.maven.scm.util.ThreadSafeDateFormat;
import org.codehaus.plexus.util.StringUtils;

/**
 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
 *
 */
public class ChangeSet
    implements Serializable
{
    /**
     *
     */
    private static final long serialVersionUID = 7097705862222539801L;

    /**
     * Escaped <code>&lt;</code> entity
     */
    public static final String LESS_THAN_ENTITY = "&lt;";

    /**
     * Escaped <code>&gt;</code> entity
     */
    public static final String GREATER_THAN_ENTITY = "&gt;";

    /**
     * Escaped <code>&amp;</code> entity
     */
    public static final String AMPERSAND_ENTITY = "&amp;";

    /**
     * Escaped <code>'</code> entity
     */
    public static final String APOSTROPHE_ENTITY = "&apos;";

    /**
     * Escaped <code>"</code> entity
     */
    public static final String QUOTE_ENTITY = "&quot;";

    private static final String DATE_PATTERN = "yyyy-MM-dd";

    /**
     * Formatter used by the getDateFormatted method.
     */
    private static final ThreadSafeDateFormat DATE_FORMAT = new ThreadSafeDateFormat( DATE_PATTERN );

    private static final String TIME_PATTERN = "HH:mm:ss";

    /**
     * Formatter used by the getTimeFormatted method.
     */
    private static final ThreadSafeDateFormat TIME_FORMAT = new ThreadSafeDateFormat( TIME_PATTERN );

    /**
     * Formatter used to parse date/timestamp.
     */
    private static final ThreadSafeDateFormat TIMESTAMP_FORMAT_1 = new ThreadSafeDateFormat( "yyyy/MM/dd HH:mm:ss" );

    private static final ThreadSafeDateFormat TIMESTAMP_FORMAT_2 = new ThreadSafeDateFormat( "yyyy-MM-dd HH:mm:ss" );

    private static final ThreadSafeDateFormat TIMESTAMP_FORMAT_3 = new ThreadSafeDateFormat( "yyyy/MM/dd HH:mm:ss z" );

    private static final ThreadSafeDateFormat TIMESTAMP_FORMAT_4 = new ThreadSafeDateFormat( "yyyy-MM-dd HH:mm:ss z" );

    /**
     * Date the changes were committed
     */
    private Date date;

    /**
     * User who made changes
     */
    private String author;

    /**
     * comment provided at commit time
     */
    private String comment = "";

    /**
     * List of ChangeFile
     */
    private List<ChangeFile> files;
    
    /**
     * The SCM revision id for this changeset.
     * @since 1.3
     */
    private String revision;

    /**
     * Revision from which this one originates
     * @since 1.7
     */
    private String parentRevision;

    /**
     * Revisions that were merged into this one
     * @since 1.7
     */
    private Set<String> mergedRevisions;

    /**
     * @param strDate         Date the changes were committed
     * @param userDatePattern pattern of date
     * @param comment         comment provided at commit time
     * @param author          User who made changes
     * @param files           The ChangeFile list
     */
    public ChangeSet( String strDate, String userDatePattern, String comment, String author,
                      List<ChangeFile> files )
    {
        this( null, comment, author, files );

        setDate( strDate, userDatePattern );
    }

    /**
     * @param date    Date the changes were committed
     * @param comment comment provided at commit time
     * @param author  User who made changes
     * @param files   The ChangeFile list
     */
    public ChangeSet( Date date, String comment, String author, List<ChangeFile> files )
    {
        setDate( date );

        setAuthor( author );

        setComment( comment );

        this.files = files;
    }

    /**
     * Constructor used when attributes aren't available until later
     */
    public ChangeSet()
    {
        // no op
    }

    /**
     * Getter for ChangeFile list.
     *
     * @return List of ChangeFile.
     */
    public List<ChangeFile> getFiles()
    {
        if ( files == null )
        {
            return new ArrayList<ChangeFile>();
        }
        return files;
    }

    /**
     * Setter for ChangeFile list.
     *
     * @param files List of ChangeFiles.
     */
    public void setFiles( List<ChangeFile> files )
    {
        this.files = files;
    }

    public void addFile( ChangeFile file )
    {
        if ( files == null )
        {
            files = new ArrayList<ChangeFile>();
        }

        files.add( file );
    }

    /**
     * @deprecated Use method {@link #containsFilename(String)}
     * @param filename
     * @param repository NOT USED
     * @return
     */
    public boolean containsFilename( String filename, ScmProviderRepository repository )
    {
        return containsFilename( filename );
    }

    public boolean containsFilename( String filename )
    {
        if ( files != null )
        {
            for ( ChangeFile file : files )
            {
                String f1 = FilenameUtils.normalizeFilename( file.getName() );
                String f2 = FilenameUtils.normalizeFilename( filename );
                if ( f1.indexOf( f2 ) >= 0 )
                {
                    return true;
                }
            }
        }

        return false;
    }

    /**
     * Getter for property author.
     *
     * @return Value of property author.
     */
    public String getAuthor()
    {
        return author;
    }

    /**
     * Setter for property author.
     *
     * @param author New value of property author.
     */
    public void setAuthor( String author )
    {
        this.author = author;
    }

    /**
     * Getter for property comment.
     *
     * @return Value of property comment.
     */
    public String getComment()
    {
        return comment;
    }

    /**
     * Setter for property comment.
     *
     * @param comment New value of property comment.
     */
    public void setComment( String comment )
    {
        this.comment = comment;
    }

    /**
     * Getter for property date.
     *
     * @return Value of property date.
     */
    public Date getDate()
    {
        if ( date != null )
        {
            return (Date) date.clone();
        }

        return null;
    }

    /**
     * Setter for property date.
     *
     * @param date New value of property date.
     */
    public void setDate( Date date )
    {
        if ( date != null )
        {
            this.date = new Date( date.getTime() );
        }
    }

    /**
     * Setter for property date that takes a string and parses it
     *
     * @param date - a string in yyyy/MM/dd HH:mm:ss format
     */
    public void setDate( String date )
    {
        setDate( date, null );
    }

    /**
     * Setter for property date that takes a string and parses it
     *
     * @param date            - a string in yyyy/MM/dd HH:mm:ss format
     * @param userDatePattern - pattern of date
     */
    public void setDate( String date, String userDatePattern )
    {
        try
        {
            if ( !StringUtils.isEmpty( userDatePattern ) )
            {
                SimpleDateFormat format = new SimpleDateFormat( userDatePattern );

                this.date = format.parse( date );
            }
            else
            {
                this.date = TIMESTAMP_FORMAT_3.parse( date );
            }
        }
        catch ( ParseException e )
        {
            if ( !StringUtils.isEmpty( userDatePattern ) )
            {
                try
                {
                    this.date = TIMESTAMP_FORMAT_3.parse( date );
                }
                catch ( ParseException pe )
                {
                    try
                    {
                        this.date = TIMESTAMP_FORMAT_4.parse( date );
                    }
                    catch ( ParseException pe1 )
                    {
                        try
                        {
                            this.date = TIMESTAMP_FORMAT_1.parse( date );
                        }
                        catch ( ParseException pe2 )
                        {
                            try
                            {
                                this.date = TIMESTAMP_FORMAT_2.parse( date );
                            }
                            catch ( ParseException pe3 )
                            {
                                throw new IllegalArgumentException( "Unable to parse date: " + date );
                            }
                        }
                    }
                }
            }
            else
            {
                try
                {
                    this.date = TIMESTAMP_FORMAT_4.parse( date );
                }
                catch ( ParseException pe1 )
                {
                    try
                    {
                        this.date = TIMESTAMP_FORMAT_1.parse( date );
                    }
                    catch ( ParseException pe2 )
                    {
                        try
                        {
                            this.date = TIMESTAMP_FORMAT_2.parse( date );
                        }
                        catch ( ParseException pe3 )
                        {
                            throw new IllegalArgumentException( "Unable to parse date: " + date );
                        }
                    }
                }
            }
        }
    }

    /**
     * @return date in yyyy-mm-dd format
     */
    public String getDateFormatted()
    {
        return DATE_FORMAT.format( getDate() );
    }

    /**
     * @return time in HH:mm:ss format
     */
    public String getTimeFormatted()
    {
        return TIME_FORMAT.format( getDate() );
    }

    /**
     * @return
     * @since 1.3
     */
    public String getRevision()
    {
        return revision;
    }

    /**
     * @param revision
     * @since 1.3
     */
    public void setRevision( String revision )
    {
        this.revision = revision;
    }

    public String getParentRevision()
    {
        return parentRevision;
    }

    public void setParentRevision( String parentRevision )
    {
        this.parentRevision = parentRevision;
    }

    public void addMergedRevision( String mergedRevision )
    {
        if ( mergedRevisions == null )
        {
            mergedRevisions = new LinkedHashSet<String>();
        }
        mergedRevisions.add( mergedRevision );
    }

    public Set<String> getMergedRevisions()
    {
        return mergedRevisions == null ? Collections.<String>emptySet() : mergedRevisions;
    }

    public void setMergedRevisions( Set<String> mergedRevisions )
    {
        this.mergedRevisions = mergedRevisions;
    }

    /** {@inheritDoc} */
    public String toString()
    {
        StringBuilder result = new StringBuilder( author == null ? " null " : author );
        result.append( "\n" ).append( date == null ? "null " : date.toString() ).append( "\n" );
        // parent(s)
        if ( parentRevision != null )
        {
            result.append( "parent: " ).append( parentRevision );
            if ( !mergedRevisions.isEmpty() )
            {
                result.append( " + " );
                result.append( mergedRevisions );
            }
            result.append( "\n" );
        }
        if ( files != null )
        {
            for ( ChangeFile file : files )
            {
                result.append( file == null ? " null " : file.toString() ).append( "\n" );
            }
        }

        result.append( comment == null ? " null " : comment );

        return result.toString();
    }

    /**
     * Provide the changelog entry as an XML snippet.
     *
     * @return a changelog-entry in xml format
     * @task make sure comment doesn't contain CDATA tags - MAVEN114
     */
    public String toXML()
    {
        StringBuilder buffer = new StringBuilder( "\t<changelog-entry>\n" );

        if ( getDate() != null )
        {
            buffer.append( "\t\t<date pattern=\"" + DATE_PATTERN + "\">" )
                .append( getDateFormatted() )
                .append( "</date>\n" )
                .append( "\t\t<time pattern=\"" + TIME_PATTERN + "\">" )
                .append( getTimeFormatted() )
                .append( "</time>\n" );
        }

        buffer.append( "\t\t<author><![CDATA[" )
            .append( author )
            .append( "]]></author>\n" );

        if ( parentRevision != null )
        {
            buffer.append( "\t\t<parent>" ).append( getParentRevision() ).append( "</parent>\n" );
        }
        for ( String mergedRevision : getMergedRevisions() )
        {
            buffer.append( "\t\t<merge>" ).append( mergedRevision ).append( "</merge>\n" );
        }

        if ( files != null )
        {
            for ( ChangeFile file : files )
            {
                buffer.append( "\t\t<file>\n" );
                if ( file.getAction() != null )
                {
                    buffer.append( "\t\t\t<action>" ).append( file.getAction() ).append( "</action>\n" );
                }
                buffer.append( "\t\t\t<name>" ).append( escapeValue( file.getName() ) ).append( "</name>\n" );
                buffer.append( "\t\t\t<revision>" ).append( file.getRevision() ).append( "</revision>\n" );
                if ( file.getOriginalName() != null )
                {
                    buffer.append( "\t\t\t<orig-name>" );
                    buffer.append( escapeValue( file.getOriginalName() ) );
                    buffer.append( "</orig-name>\n" );
                }
                if ( file.getOriginalRevision() != null )
                {
                    buffer.append( "\t\t\t<orig-revision>" );
                    buffer.append( file.getOriginalRevision() );
                    buffer.append( "</orig-revision>\n" );
                }
                buffer.append( "\t\t</file>\n" );
            }
        }
        buffer.append( "\t\t<msg><![CDATA[" )
            .append( removeCDataEnd( comment ) )
            .append( "]]></msg>\n" );
        buffer.append( "\t</changelog-entry>\n" );

        return buffer.toString();
    }

    /** {@inheritDoc} */
    public boolean equals( Object obj )
    {
        if ( obj instanceof ChangeSet )
        {
            ChangeSet changeSet = (ChangeSet) obj;

            if ( toString().equals( changeSet.toString() ) )
            {
                return true;
            }
        }

        return false;
    }

    /** {@inheritDoc} */
    public int hashCode()
    {
        final int prime = 31;
        int result = 1;
        result = prime * result + ( ( author == null ) ? 0 : author.hashCode() );
        result = prime * result + ( ( comment == null ) ? 0 : comment.hashCode() );
        result = prime * result + ( ( date == null ) ? 0 : date.hashCode() );
        result = prime * result + ( ( parentRevision == null ) ? 0 : parentRevision.hashCode() );
        result = prime * result + ( ( mergedRevisions == null ) ? 0 : mergedRevisions.hashCode() );
        result = prime * result + ( ( files == null ) ? 0 : files.hashCode() );
        return result;
    }

    /**
     * remove a <code>]]></code> from comments (replace it with <code>] ] ></code>).
     *
     * @param message The message to modify
     * @return a clean string
     */
    private String removeCDataEnd( String message )
    {
        // check for invalid sequence ]]>
        int endCdata;
        while ( message != null && ( endCdata = message.indexOf( "]]>" ) ) > -1 )
        {
            message = message.substring( 0, endCdata ) + "] ] >" + message.substring( endCdata + 3, message.length() );
        }
        return message;
    }

    /**
     * <p>Escape the <code>toString</code> of the given object.
     * For use in an attribute value.</p>
     * <p/>
     * swiped from jakarta-commons/betwixt -- XMLUtils.java
     *
     * @param value escape <code>value.toString()</code>
     * @return text with characters restricted (for use in attributes) escaped
     */
    public static String escapeValue( Object value )
    {
        StringBuilder buffer = new StringBuilder( value.toString() );
        for ( int i = 0, size = buffer.length(); i < size; i++ )
        {
            switch ( buffer.charAt( i ) )
            {
                case'<':
                    buffer.replace( i, i + 1, LESS_THAN_ENTITY );
                    size += 3;
                    i += 3;
                    break;
                case'>':
                    buffer.replace( i, i + 1, GREATER_THAN_ENTITY );
                    size += 3;
                    i += 3;
                    break;
                case'&':
                    buffer.replace( i, i + 1, AMPERSAND_ENTITY );
                    size += 4;
                    i += 4;
                    break;
                case'\'':
                    buffer.replace( i, i + 1, APOSTROPHE_ENTITY );
                    size += 5;
                    i += 5;
                    break;
                case'\"':
                    buffer.replace( i, i + 1, QUOTE_ENTITY );
                    size += 5;
                    i += 5;
                    break;
                default:
            }
        }
        return buffer.toString();
    }
}
