/*
 *  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.shared.ldap.codec.controls.search.entryChange;


import org.apache.directory.shared.asn1.DecoderException;
import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar;
import org.apache.directory.shared.asn1.ber.grammar.Grammar;
import org.apache.directory.shared.asn1.ber.grammar.GrammarAction;
import org.apache.directory.shared.asn1.ber.grammar.GrammarTransition;
import org.apache.directory.shared.asn1.ber.tlv.IntegerDecoder;
import org.apache.directory.shared.asn1.ber.tlv.IntegerDecoderException;
import org.apache.directory.shared.asn1.ber.tlv.LongDecoder;
import org.apache.directory.shared.asn1.ber.tlv.LongDecoderException;
import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
import org.apache.directory.shared.asn1.ber.tlv.Value;
import org.apache.directory.shared.i18n.I18n;
import org.apache.directory.shared.ldap.model.exception.LdapInvalidDnException;
import org.apache.directory.shared.ldap.model.message.controls.ChangeType;
import org.apache.directory.shared.ldap.model.name.Dn;
import org.apache.directory.shared.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * This class implements the EntryChangeControl. All the actions are declared in
 * this class. As it is a singleton, these declaration are only done once.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public final class EntryChangeGrammar extends AbstractGrammar<EntryChangeContainer>
{
    /** The logger */
    static final Logger LOG = LoggerFactory.getLogger( EntryChangeGrammar.class );

    /** Speedup for logs */
    static final boolean IS_DEBUG = LOG.isDebugEnabled();

    /** The instance of grammar. EntryChangeGrammar is a singleton */
    private static Grammar<?> instance = new EntryChangeGrammar();


    /**
     * Creates a new EntryChangeGrammar object.
     */
    @SuppressWarnings("unchecked")
    private EntryChangeGrammar()
    {
        setName( EntryChangeGrammar.class.getName() );

        // Create the transitions table
        super.transitions = new GrammarTransition[ EntryChangeStates.LAST_EC_STATE.ordinal()][256];

        // ============================================================================================
        // Transition from start state to Entry Change sequence
        // ============================================================================================
        // EntryChangeNotification ::= SEQUENCE {
        //     ...
        //
        // Initialization of the structure
        super.transitions[ EntryChangeStates.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] =
            new GrammarTransition<EntryChangeContainer>( EntryChangeStates.START_STATE,
                                    EntryChangeStates.EC_SEQUENCE_STATE,
                                    UniversalTag.SEQUENCE.getValue(), null );

        // ============================================================================================
        // transition from Entry Change sequence to Change Type
        // ============================================================================================
        // EntryChangeNotification ::= SEQUENCE {
        //     changeType ENUMERATED {
        //     ...
        //
        // Evaluates the changeType
        super.transitions[ EntryChangeStates.EC_SEQUENCE_STATE.ordinal()][UniversalTag.ENUMERATED.getValue()] =
            new GrammarTransition<EntryChangeContainer>( EntryChangeStates.EC_SEQUENCE_STATE,
                                    EntryChangeStates.CHANGE_TYPE_STATE,
                                    UniversalTag.ENUMERATED.getValue(),
            new GrammarAction<EntryChangeContainer>( "Set EntryChangeControl changeType" )
        {
            public void action( EntryChangeContainer container ) throws DecoderException
            {
                Value value = container.getCurrentTLV().getValue();

                try
                {
                    int change = IntegerDecoder.parse( value, 1, 8 );
                    
                    switch ( ChangeType.getChangeType( change ) )
                    {
                        case ADD:
                        case DELETE:
                        case MODDN:
                        case MODIFY:
                            ChangeType changeType = ChangeType.getChangeType( change );

                            if ( IS_DEBUG )
                            {
                                LOG.debug( "changeType = " + changeType );
                            }

                            container.getEntryChangeDecorator().setChangeType( changeType );
                            break;

                        default:
                            String msg = I18n.err( I18n.ERR_04044 );
                            LOG.error( msg );
                            throw new DecoderException( msg );
                    }

                    // We can have an END transition
                    container.setGrammarEndAllowed( true );
                }
                catch ( IntegerDecoderException e )
                {
                    String msg = I18n.err( I18n.ERR_04044 );
                    LOG.error( msg, e );
                    throw new DecoderException( msg );
                }
                catch ( IllegalArgumentException e )
                {
                    throw new DecoderException( e.getLocalizedMessage() );
                }
            }
        } );

        // ============================================================================================
        // Transition from Change Type to Previous Dn
        // ============================================================================================
        // EntryChangeNotification ::= SEQUENCE {
        //     ...
        //     previousDN LDAPDN OPTIONAL,
        //     ...
        //
        // Set the previousDN into the structure. We first check that it's a
        // valid Dn
        super.transitions[ EntryChangeStates.CHANGE_TYPE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] =
            new GrammarTransition<EntryChangeContainer>( EntryChangeStates.CHANGE_TYPE_STATE,
                                    EntryChangeStates.PREVIOUS_DN_STATE,
                                    UniversalTag.OCTET_STRING.getValue(),
            new GrammarAction<EntryChangeContainer>( "Set EntryChangeControl previousDN" )
        {
            public void action( EntryChangeContainer container ) throws DecoderException
            {
                ChangeType changeType = container.getEntryChangeDecorator().getChangeType();


                if ( changeType != ChangeType.MODDN )
                {
                    LOG.error( I18n.err( I18n.ERR_04045 ) );
                    throw new DecoderException( I18n.err( I18n.ERR_04046 ));
                }
                else
                {
                    Value value = container.getCurrentTLV().getValue();
                    Dn previousDn;

                    try
                    {
                        previousDn = new Dn( Strings.utf8ToString(value.getData()) );
                    }
                    catch ( LdapInvalidDnException ine )
                    {
                        LOG.error( I18n.err( I18n.ERR_04047, Strings.dumpBytes(value.getData()) ) );
                        throw new DecoderException( I18n.err( I18n.ERR_04048 ) );
                    }

                    if ( IS_DEBUG )
                    {
                        LOG.debug( "previousDN = " + previousDn );
                    }

                    container.getEntryChangeDecorator().setPreviousDn( previousDn );

                    // We can have an END transition
                    container.setGrammarEndAllowed( true );
                }
            }
        } );

        // Change Number action
        GrammarAction<EntryChangeContainer> setChangeNumberAction = new GrammarAction<EntryChangeContainer>( "Set EntryChangeControl changeNumber" )
        {
            public void action( EntryChangeContainer container ) throws DecoderException
            {
                Value value = container.getCurrentTLV().getValue();

                try
                {
                    long changeNumber = LongDecoder.parse( value );

                    if ( IS_DEBUG )
                    {
                        LOG.debug( "changeNumber = " + changeNumber );
                    }

                    container.getEntryChangeDecorator().setChangeNumber( changeNumber );

                    // We can have an END transition
                    container.setGrammarEndAllowed( true );
                }
                catch ( LongDecoderException e )
                {
                    String msg = I18n.err( I18n.ERR_04049 );
                    LOG.error( msg, e );
                    throw new DecoderException( msg );
                }
            }
        };

        // ============================================================================================
        // Transition from Previous Dn to Change Number
        // ============================================================================================
        // EntryChangeNotification ::= SEQUENCE {
        //     ...
        //     changeNumber INTEGER OPTIONAL
        // }
        //
        // Set the changeNumber into the structure
        super.transitions[ EntryChangeStates.PREVIOUS_DN_STATE.ordinal()][UniversalTag.INTEGER.getValue()] =
            new GrammarTransition<EntryChangeContainer>( EntryChangeStates.PREVIOUS_DN_STATE,
                                    EntryChangeStates.CHANGE_NUMBER_STATE,
                                    UniversalTag.INTEGER.getValue(),
                setChangeNumberAction );

        // ============================================================================================
        // Transition from Previous Dn to Change Number
        // ============================================================================================
        // EntryChangeNotification ::= SEQUENCE {
        //     ...
        //     changeNumber INTEGER OPTIONAL
        // }
        //
        // Set the changeNumber into the structure
        super.transitions[ EntryChangeStates.CHANGE_TYPE_STATE.ordinal()][UniversalTag.INTEGER.getValue()] =
            new GrammarTransition<EntryChangeContainer>( EntryChangeStates.CHANGE_TYPE_STATE,
                                    EntryChangeStates.CHANGE_NUMBER_STATE,
                                    UniversalTag.INTEGER.getValue(),
                setChangeNumberAction );
    }


    /**
     * This class is a singleton.
     * 
     * @return An instance on this grammar
     */
    public static Grammar<?> getInstance()
    {
        return instance;
    }
}
