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 org.apache.maven.scm.provider.ScmProviderRepository;
import org.codehaus.plexus.util.StringUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

/**
 * @author <a href="mailto:evenisse@apache.org">Emmanuel Venisse</a>
 * @version $Id$
 */
public class ChangeSet
{
    /**
     * 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 SimpleDateFormat DATE_FORMAT = new SimpleDateFormat( DATE_PATTERN );

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

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

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

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

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

    private static final SimpleDateFormat TIMESTAMP_FORMAT_4 = new SimpleDateFormat( "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;

    /**
     * @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()
    {
    }

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

        files.add( file );
    }

    public boolean containsFilename( String filename, ScmProviderRepository repository )
    {
        if ( files != null )
        {
            for ( Iterator i = files.iterator(); i.hasNext(); )
            {
                ChangeFile file = (ChangeFile) i.next();
                String f1 = StringUtils.replace( StringUtils.replace( file.getName(), "\\", "/" ), "//", "/" );
                String f2 = StringUtils.replace( StringUtils.replace( 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 synchronized String getDateFormatted()
    {
        return DATE_FORMAT.format( getDate() );
    }

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

    /**
     * @return Returns string representation of the changeset
     */
    public String toString()
    {
        String result = author + "\n" + date + "\n";

        if ( files != null )
        {
            for ( Iterator i = files.iterator(); i.hasNext(); )
            {
                ChangeFile file = (ChangeFile) i.next();

                result += file + "\n";
            }
        }

        result += comment;

        return result;
    }

    /**
     * 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()
    {
        StringBuffer buffer = new StringBuffer();

        buffer.append( "\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" );

        for ( Iterator i = files.iterator(); i.hasNext(); )
        {
            ChangeFile file = (ChangeFile) i.next();
            buffer.append( "\t\t<file>\n" )
                .append( "\t\t\t<name>" )
                .append( escapeValue( file.getName() ) )
                .append( "</name>\n" )
                .append( "\t\t\t<revision>" )
                .append( file.getRevision() )
                .append( "</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();
    }

    /**
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals( Object obj )
    {
        if ( obj instanceof ChangeSet )
        {
            ChangeSet changeSet = (ChangeSet) obj;

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

        return false;
    }

    /**
     * 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 )
    {
        StringBuffer buffer = new StringBuffer( 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 += 4;
                    i += 4;
                    break;
                case'\"':
                    buffer.replace( i, i + 1, QUOTE_ENTITY );
                    size += 5;
                    i += 5;
                    break;
            }
        }
        return buffer.toString();
    }
}
