/*
 *  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. 
 *  
 */
package org.apache.directory.api.ldap.model.csn;


import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

import org.apache.directory.api.i18n.I18n;
import org.apache.directory.api.util.Chars;
import org.apache.directory.api.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Represents 'Change Sequence Number' in LDUP specification.
 * 
 * A CSN is a composition of a timestamp, a replica ID and a 
 * operation sequence number.
 * 
 * It's described in http://tools.ietf.org/html/draft-ietf-ldup-model-09.
 * 
 * The CSN syntax is :
 * <pre>
 * &lt;CSN&gt;            ::= &lt;timestamp&gt; # &lt;changeCount&gt; # &lt;replicaId&gt; # &lt;modifierNumber&gt;
 * &lt;timestamp&gt;      ::= A GMT based time, YYYYmmddHHMMSS.uuuuuuZ
 * &lt;changeCount&gt;    ::= [000000-ffffff] 
 * &lt;replicaId&gt;      ::= [000-fff]
 * &lt;modifierNumber&gt; ::= [000000-ffffff]
 * </pre>
 *  
 * It distinguishes a change made on an object on a server,
 * and if two operations take place during the same timeStamp,
 * the operation sequence number makes those operations distinct.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class Csn implements Comparable<Csn>
{
    /** The logger for this class */
    private static final Logger LOG = LoggerFactory.getLogger( Csn.class );

    /** The timeStamp of this operation */
    private final long timestamp;

    /** The server identification */
    private final int replicaId;

    /** The operation number in a modification operation */
    private final int operationNumber;

    /** The changeCount to distinguish operations done in the same second */
    private final int changeCount;

    /** Stores the String representation of the CSN */
    private String csnStr;

    /** Stores the byte array representation of the CSN */
    private byte[] bytes;

    /** The Timestamp syntax. The last 'z' is _not_ the Time Zone */
    private final SimpleDateFormat sdf = new SimpleDateFormat( "yyyyMMddHHmmss", Locale.ROOT );

    private static final TimeZone UTC_TIME_ZONE = TimeZone.getTimeZone( "UTC" );

    /** Padding used to format number with a fixed size */
    private static final String[] PADDING_6 = new String[]
        { "00000", "0000", "000", "00", "0", "" };

    /** Padding used to format number with a fixed size */
    private static final String[] PADDING_3 = new String[]
        { "00", "0", "" };


    /**
     * Creates a new instance.
     * <b>This method should be used only for deserializing a CSN</b> 
     * 
     * @param timestamp GMT timestamp of modification
     * @param changeCount The operation increment
     * @param replicaId Replica ID where modification occurred (<tt>[-_A-Za-z0-9]{1,16}</tt>)
     * @param operationNumber Operation number in a modification operation
     */
    public Csn( long timestamp, int changeCount, int replicaId, int operationNumber )
    {
        this.timestamp = timestamp;
        this.replicaId = replicaId;
        this.operationNumber = operationNumber;
        this.changeCount = changeCount;
        sdf.setTimeZone( UTC_TIME_ZONE );
    }


    /**
     * Creates a new instance of SimpleCSN from a String.
     * 
     * The string format must be :
     * &lt;timestamp&gt; # &lt;changeCount&gt; # &lt;replica ID&gt; # &lt;operation number&gt;
     *
     * @param value The String containing the CSN
     */
    public Csn( String value )
    {
        sdf.setTimeZone( UTC_TIME_ZONE );
        
        if ( Strings.isEmpty( value ) )
        {
            String message = I18n.err( I18n.ERR_13015_NULL_OR_EMPTY_CSN );
            LOG.error( message );
            throw new InvalidCSNException( message );
        }

        if ( value.length() != 40 )
        {
            String message = I18n.err( I18n.ERR_13016_INCORRECT_CSN_LENGTH );
            LOG.error( message );
            throw new InvalidCSNException( message );
        }

        // Get the Timestamp
        int sepTS = value.indexOf( '#' );

        if ( sepTS < 0 )
        {
            String message = I18n.err( I18n.ERR_13017_CANT_FIND_SHARP_IN_CSN );
            LOG.error( message );
            throw new InvalidCSNException( message );
        }

        String timestampStr = value.substring( 0, sepTS ).trim();

        if ( timestampStr.length() != 22 )
        {
            String message = I18n.err( I18n.ERR_13018_TIMESTAMP_NOT_LONG_ENOUGH );
            LOG.error( message );
            throw new InvalidCSNException( message );
        }

        // Let's transform the Timestamp by removing the mulliseconds and microseconds
        String realTimestamp = timestampStr.substring( 0, 14 );

        long tempTimestamp = 0L;

        synchronized ( sdf )
        {
            try
            {
                tempTimestamp = sdf.parse( realTimestamp ).getTime();
            }
            catch ( ParseException pe )
            {
                String message = I18n.err( I18n.ERR_13019_CANNOT_PARSE_TIMESTAMP, timestampStr );
                LOG.error( message );
                throw new InvalidCSNException( message, pe );
            }
        }

        int millis = 0;

        // And add the milliseconds and microseconds now
        try
        {
            millis = Integer.parseInt( timestampStr.substring( 15, 21 ) );
        }
        catch ( NumberFormatException nfe )
        {
            String message = I18n.err( I18n.ERR_13020_INVALID_MICROSECOND );
            LOG.error( message );
            throw new InvalidCSNException( message, nfe );
        }

        tempTimestamp += ( millis / 1000 );
        timestamp = tempTimestamp;

        // Get the changeCount. It should be an hex number prefixed with '0x'
        int sepCC = value.indexOf( '#', sepTS + 1 );

        if ( sepCC < 0 )
        {
            String message = I18n.err( I18n.ERR_13014_DN_ATTR_FLAG_INVALID, value );
            LOG.error( message );
            throw new InvalidCSNException( message );
        }

        String changeCountStr = value.substring( sepTS + 1, sepCC ).trim();

        try
        {
            changeCount = Integer.parseInt( changeCountStr, 16 );
        }
        catch ( NumberFormatException nfe )
        {
            String message = I18n.err( I18n.ERR_13021_INVALID_CHANGE_COUNT, changeCountStr );
            LOG.error( message );
            throw new InvalidCSNException( message, nfe );
        }

        // Get the replicaID
        int sepRI = value.indexOf( '#', sepCC + 1 );

        if ( sepRI < 0 )
        {
            String message = I18n.err( I18n.ERR_13022_MISSING_SHARP_IN_CSN, value );
            LOG.error( message );
            throw new InvalidCSNException( message );
        }

        String replicaIdStr = value.substring( sepCC + 1, sepRI ).trim();

        if ( Strings.isEmpty( replicaIdStr ) )
        {
            String message = I18n.err( I18n.ERR_13023_REPLICA_ID_NULL );
            LOG.error( message );
            throw new InvalidCSNException( message );
        }

        try
        {
            replicaId = Integer.parseInt( replicaIdStr, 16 );
        }
        catch ( NumberFormatException nfe )
        {
            String message = I18n.err( I18n.ERR_13024_INVALID_REPLICA_ID, replicaIdStr );
            LOG.error( message );
            throw new InvalidCSNException( message, nfe );
        }

        // Get the modification number
        if ( sepCC == value.length() )
        {
            String message = I18n.err( I18n.ERR_13025_NO_OPERATION_NUMBER );
            LOG.error( message );
            throw new InvalidCSNException( message );
        }

        String operationNumberStr = value.substring( sepRI + 1 ).trim();

        try
        {
            operationNumber = Integer.parseInt( operationNumberStr, 16 );
        }
        catch ( NumberFormatException nfe )
        {
            String message = I18n.err( I18n.ERR_13026_INVALID_OPERATION_NUMBER, operationNumberStr );
            LOG.error( message );
            throw new InvalidCSNException( message, nfe );
        }

        csnStr = value;
        bytes = Strings.getBytesUtf8( csnStr );
    }


    /**
     * Creates a new instance of SimpleCSN from the serialized data
     *
     * @param value The byte array which contains the serialized CSN
     */
    Csn( byte[] value )
    {
        csnStr = Strings.utf8ToString( value );
        Csn csn = new Csn( csnStr );
        timestamp = csn.timestamp;
        changeCount = csn.changeCount;
        replicaId = csn.replicaId;
        operationNumber = csn.operationNumber;
        bytes = Strings.getBytesUtf8( csnStr );
    }

    
    /**
     * Check if the given String is a valid CSN.
     * 
     * @param value The String to check
     * @return <code>true</code> if the String is a valid CSN
     */
    public static boolean isValid( String value )
    {
        if ( Strings.isEmpty( value ) )
        {
            return false;
        }

        char[] chars = value.toCharArray();
        
        if ( chars.length != 40 )
        {
            return false;
        }

        // Get the Timestamp
        // Check the timestamp's year
        for ( int pos = 0; pos < 4; pos++ )
        {
            if ( !Chars.isDigit( chars[pos] ) )
            {
                return false;
            }
        }
        
        // Check the timestamp month
        switch ( chars[4] )
        {
            case '0' :
                if ( !Chars.isDigit( chars[5] ) )
                {
                    return false;
                }
                
                if ( chars[5] == '0' )
                {
                    return false;
                }
                
                break;
                
            case '1' :
                if ( ( chars[5] != '0' ) && ( chars[5] != '1' ) && ( chars[5] != '2' ) )
                {
                    return false;
                }
                
                break;
                
            default :
                return false;
        }

        // Check the timestamp day
        switch ( chars[6] )
        {
            case '0' :
                if ( !Chars.isDigit( chars[7] ) )
                {
                    return false;
                }
                
                if ( chars[7] == '0' )
                {
                    return false;
                }
                
                break;
                
            case '1' :
            case '2' : // Special case for february...
                if ( !Chars.isDigit( chars[7] ) )
                {
                    return false;
                }
                
                break;
                
            case '3' :
                // Deal with 30 days months
                if ( ( chars[7] != '0' ) && ( chars[7] != '1' ) )
                {
                    return false;
                }
                
                break;
                
            default :
                return false;
        }

        // Check the timestamp hour
        switch ( chars[8] )
        {
            case '0' :
            case '1' :
                if ( !Chars.isDigit( chars[9] ) )
                {
                    return false;
                }

                break;
                
            case '2' :
                if ( ( chars[9] != '0' ) && ( chars[9] != '1' ) && ( chars[9] != '2' ) && ( chars[9] != '3' ) )
                {
                    return false;
                }
                
                break;
                
            default :
                return false;
        }

        // Check the timestamp minute
        switch ( chars[10] )
        {
            case '0' :
            case '1' :
            case '2' :
            case '3' :
            case '4' :
            case '5' :
                break;
                
            default :
                return false;
        }
        
        if ( !Chars.isDigit( chars[11] ) )
        {
            return false;
        }
        
        // Check the timestamp seconds
        switch ( chars[12] )
        {
            case '0' :
            case '1' :
            case '2' :
            case '3' :
            case '4' :
            case '5' :
                break;
                
            default :
                return false;
        }
        
        if ( !Chars.isDigit( chars[13] ) )
        {
            return false;
        }

        // Check the milliseconds
        if ( chars[14] != '.' )
        {
            return false;
        }

        for ( int i = 0; i < 6; i++ )
        {
            if ( !Chars.isDigit( chars[15 + i] ) )
            {
                return false;
            }
        }

        if ( chars[21] != 'Z' )
        {
            return false;
        }

        if ( chars[22] != '#' )
        {
            return false;
        }

        // Get the changeCount. It should be an 6 digit hex number
        if ( !Chars.isHex( ( byte ) chars[23] )
            || !Chars.isHex( ( byte ) chars[24] )
            || !Chars.isHex( ( byte ) chars[25] )
            || !Chars.isHex( ( byte ) chars[26] )
            || !Chars.isHex( ( byte ) chars[27] )
            || !Chars.isHex( ( byte ) chars[28] ) )
        {
            return false;
        }

        if ( chars[29] != '#' )
        {
            return false;
        }
        
        // Get the replicaID, which should be a 3 digits hex number
        if ( !Chars.isHex( ( byte ) chars[30] )
            || !Chars.isHex( ( byte ) chars[31] )
            || !Chars.isHex( ( byte ) chars[32] ) )
        {
            return false;
        }

        if ( chars[33] != '#' )
        {
            return false;
        }

        // Check the modification number, which should be a 6 digits hex number
        if ( !Chars.isHex( ( byte ) chars[34] )
            || !Chars.isHex( ( byte ) chars[35] )
            || !Chars.isHex( ( byte ) chars[36] )
            || !Chars.isHex( ( byte ) chars[37] )
            || !Chars.isHex( ( byte ) chars[38] )
            || !Chars.isHex( ( byte ) chars[39] ) )
        {
            return false;
        }

        return true;
    }


    /**
     * Get the CSN as a byte array. The data are stored as :
     * bytes 1 to 8  : timestamp, big-endian
     * bytes 9 to 12 : change count, big endian
     * bytes 13 to ... : ReplicaId 
     * 
     * @return A copy of the byte array representing theCSN
     */
    public byte[] getBytes()
    {
        if ( bytes == null )
        {
            bytes = Strings.getBytesUtf8( csnStr );
        }

        byte[] copy = new byte[bytes.length];
        System.arraycopy( bytes, 0, copy, 0, bytes.length );
        return copy;
    }


    /**
     * @return The timestamp
     */
    public long getTimestamp()
    {
        return timestamp;
    }


    /**
     * @return The changeCount
     */
    public int getChangeCount()
    {
        return changeCount;
    }


    /**
     * @return The replicaId
     */
    public int getReplicaId()
    {
        return replicaId;
    }


    /**
     * @return The operation number
     */
    public int getOperationNumber()
    {
        return operationNumber;
    }


    /**
     * @return The CSN as a String
     */
    @Override
    public String toString()
    {
        if ( csnStr == null )
        {
            StringBuilder buf = new StringBuilder( 40 );

            synchronized ( sdf )
            {
                buf.append( sdf.format( new Date( timestamp ) ) );
            }

            // Add the milliseconds part
            long millis = ( timestamp % 1000 ) * 1000;
            String millisStr = Long.toString( millis );

            buf.append( '.' ).append( PADDING_6[millisStr.length() - 1] ).append( millisStr ).append( "Z#" );

            String countStr = Integer.toHexString( changeCount );

            buf.append( PADDING_6[countStr.length() - 1] ).append( countStr );
            buf.append( '#' );

            String replicaIdStr = Integer.toHexString( replicaId );

            buf.append( PADDING_3[replicaIdStr.length() - 1] ).append( replicaIdStr );
            buf.append( '#' );

            String operationNumberStr = Integer.toHexString( operationNumber );

            buf.append( PADDING_6[operationNumberStr.length() - 1] ).append( operationNumberStr );

            csnStr = buf.toString();
        }

        return csnStr;
    }


    /**
     * Returns a hash code value for the object.
     * 
     * @return a hash code value for this object.
     */
    @Override
    public int hashCode()
    {
        int h = 37;

        h = h * 17 + ( int ) ( timestamp ^ ( timestamp >>> 32 ) );
        h = h * 17 + changeCount;
        h = h * 17 + replicaId;
        h = h * 17 + operationNumber;

        return h;
    }


    /**
     * Indicates whether some other object is "equal to" this one
     * 
     * @param o the reference object with which to compare.
     * @return <code>true</code> if this object is the same as the obj argument; 
     * <code>false</code> otherwise.
     */
    @Override
    public boolean equals( Object o )
    {
        if ( this == o )
        {
            return true;
        }

        if ( !( o instanceof Csn ) )
        {
            return false;
        }

        Csn that = ( Csn ) o;

        return ( timestamp == that.timestamp ) && ( changeCount == that.changeCount )
            && ( replicaId == that.replicaId ) && ( operationNumber == that.operationNumber );
    }


    /**
     * Compares this object with the specified object for order.  Returns a
     * negative integer, zero, or a positive integer as this object is less
     * than, equal to, or greater than the specified object.<p>
     * 
     * @param   csn the Object to be compared.
     * @return  a negative integer, zero, or a positive integer as this object
     *      is less than, equal to, or greater than the specified object.
     */
    @Override
    public int compareTo( Csn csn )
    {
        if ( csn == null )
        {
            return 1;
        }

        // Compares the timestamp first
        if ( this.timestamp < csn.timestamp )
        {
            return -1;
        }
        else if ( this.timestamp > csn.timestamp )
        {
            return 1;
        }

        // Then the change count
        if ( this.changeCount < csn.changeCount )
        {
            return -1;
        }
        else if ( this.changeCount > csn.changeCount )
        {
            return 1;
        }

        // Then the replicaId
        int replicaIdCompareResult = getReplicaIdCompareResult( csn );

        if ( replicaIdCompareResult != 0 )
        {
            return replicaIdCompareResult;
        }

        // Last, not least, compares the operation number
        if ( this.operationNumber < csn.operationNumber )
        {
            return -1;
        }
        else if ( this.operationNumber > csn.operationNumber )
        {
            return 1;
        }
        else
        {
            return 0;
        }
    }


    private int getReplicaIdCompareResult( Csn csn )
    {
        if ( this.replicaId < csn.replicaId )
        {
            return -1;
        }
        if ( this.replicaId > csn.replicaId )
        {
            return 1;
        }
        return 0;
    }
}
