/*
 *  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.extras.extended.ads_impl;


import org.apache.directory.shared.asn1.DecoderException;
import org.apache.directory.shared.asn1.ber.grammar.AbstractGrammar;
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.TLV;
import org.apache.directory.shared.asn1.ber.tlv.UniversalTag;
import org.apache.directory.shared.i18n.I18n;
import org.apache.directory.shared.ldap.extras.extended.ads_impl.StoredProcedure.StoredProcedureParameter;
import org.apache.directory.shared.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * ASN.1 BER Grammar for Stored Procedure Extended Operation
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public final class StoredProcedureGrammar extends AbstractGrammar<StoredProcedureContainer>
{
    //~ Static fields/initializers -----------------------------------------------------------------

    /** The logger */
    //private static final Logger log = LoggerFactory.getLogger( StoredProcedureGrammar.class );
    static final Logger LOG = LoggerFactory.getLogger( StoredProcedureGrammar.class );

    /** The instance of grammar. StoredProcedureGrammar is a singleton. */
    private static StoredProcedureGrammar instance = new StoredProcedureGrammar();


    //~ Constructors -------------------------------------------------------------------------------

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

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

        //============================================================================================
        // StoredProcedure Message
        //============================================================================================
        // StoredProcedure ::= SEQUENCE {
        //   ...
        // Nothing to do.
        super.transitions[StoredProcedureStatesEnum.START_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 
            new GrammarTransition<StoredProcedureContainer>( StoredProcedureStatesEnum.START_STATE, 
                                    StoredProcedureStatesEnum.STORED_PROCEDURE_STATE, 
                                    UniversalTag.SEQUENCE.getValue(), 
                                    null );

        //    language OCTETSTRING, (Tag)
        //    ...
        //
        // Creates the storeProcedure and stores the language
        super.transitions[StoredProcedureStatesEnum.STORED_PROCEDURE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 
            new GrammarTransition<StoredProcedureContainer>( StoredProcedureStatesEnum.STORED_PROCEDURE_STATE, 
                                    StoredProcedureStatesEnum.LANGUAGE_STATE, 
                                    UniversalTag.OCTET_STRING.getValue(),
                new GrammarAction<StoredProcedureContainer>( "Stores the language" )
            {
                public void action( StoredProcedureContainer container ) throws DecoderException
                {
                    TLV tlv = container.getCurrentTLV();

                    StoredProcedure storedProcedure = null;

                    // Store the value.
                    if ( tlv.getLength() == 0 )
                    {
                        // We can't have a void language !
                        String msg = I18n.err( I18n.ERR_04038 );
                        LOG.error( msg );
                        throw new DecoderException( msg );
                    }
                    else
                    {
                        // Only this field's type is String by default
                        String language = Strings.utf8ToString(tlv.getValue().getData());

                        if ( LOG.isDebugEnabled() )
                        {
                            LOG.debug( "SP language found: " + language );
                        }

                        storedProcedure = new StoredProcedure();
                        storedProcedure.setLanguage( language );
                        container.setStoredProcedure( storedProcedure );
                    }
                }
            } );

        //    procedure OCTETSTRING, (Value)
        //    ...
        // Stores the procedure.
        super.transitions[StoredProcedureStatesEnum.LANGUAGE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 
            new GrammarTransition<StoredProcedureContainer>( StoredProcedureStatesEnum.LANGUAGE_STATE, 
                                    StoredProcedureStatesEnum.PROCEDURE_STATE, 
                                    UniversalTag.OCTET_STRING.getValue(),
                new GrammarAction<StoredProcedureContainer>( "Stores the procedure" )
            {
                public void action( StoredProcedureContainer container ) throws DecoderException
                {
                    TLV tlv = container.getCurrentTLV();

                    StoredProcedure storedProcedure = container.getStoredProcedure();

                    // Store the value.
                    if ( tlv.getLength() == 0 )
                    {
                        // We can't have a void procedure !
                        String msg = I18n.err( I18n.ERR_04039 );
                        LOG.error( msg );
                        throw new DecoderException( msg );
                    }
                    else
                    {
                        byte[] procedure = tlv.getValue().getData();

                        storedProcedure.setProcedure( procedure );
                    }

                    if ( LOG.isDebugEnabled() )
                    {
                        LOG.debug( "Procedure found : " + Strings.utf8ToString(storedProcedure.getProcedure()) );
                    }
                }
            } );

        // parameters SEQUENCE OF Parameter { (Value)
        //    ...
        // The list of parameters will be created with the first parameter.
        // We can have an empty list of parameters, so the PDU can be empty
        super.transitions[StoredProcedureStatesEnum.PROCEDURE_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 
            new GrammarTransition<StoredProcedureContainer>( StoredProcedureStatesEnum.PROCEDURE_STATE, 
                                    StoredProcedureStatesEnum.PARAMETERS_STATE, 
                                    UniversalTag.SEQUENCE.getValue(), 
            new GrammarAction<StoredProcedureContainer>( "Stores the parameters" )
            {
                public void action( StoredProcedureContainer container ) throws DecoderException
                {
                    StoredProcedureContainer storedProcedureContainer = ( StoredProcedureContainer ) container;
                    storedProcedureContainer.setGrammarEndAllowed( true );
                }
            } );
        
        // parameter SEQUENCE OF { (Value)
        //    ...
        // Nothing to do. 
        super.transitions[StoredProcedureStatesEnum.PARAMETERS_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 
            new GrammarTransition<StoredProcedureContainer>( StoredProcedureStatesEnum.PARAMETERS_STATE, 
                                    StoredProcedureStatesEnum.PARAMETER_STATE, 
                                    UniversalTag.SEQUENCE.getValue(), 
                                    null );

        // Parameter ::= {
        //    type OCTETSTRING, (Value)
        //    ...
        //
        // We can create a parameter, and store its type
        super.transitions[StoredProcedureStatesEnum.PARAMETER_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 
            new GrammarTransition<StoredProcedureContainer>( StoredProcedureStatesEnum.PARAMETER_STATE, 
                                    StoredProcedureStatesEnum.PARAMETER_TYPE_STATE, 
                                    UniversalTag.OCTET_STRING.getValue(),
                new GrammarAction<StoredProcedureContainer>( "Store parameter type" )
            {
                public void action( StoredProcedureContainer container ) throws DecoderException
                {
                    TLV tlv = container.getCurrentTLV();
                    StoredProcedure storedProcedure = container.getStoredProcedure();

                    // Store the value.
                    if ( tlv.getLength() == 0 )
                    {
                        // We can't have a void parameter type !
                        String msg = I18n.err( I18n.ERR_04040 );
                        LOG.error( msg );
                        throw new DecoderException( msg );
                    }
                    else
                    {
                        StoredProcedureParameter parameter = new StoredProcedureParameter();

                        byte[] parameterType = tlv.getValue().getData();

                        parameter.setType( parameterType );

                        // We store the type in the current parameter.
                        storedProcedure.setCurrentParameter( parameter );

                        if ( LOG.isDebugEnabled() )
                        {
                            LOG.debug( "Parameter type found : " + Strings.dumpBytes(parameterType) );
                        }

                    }
                }
            } );

        // Parameter ::= {
        //    ...
        //    value OCTETSTRING (Tag)
        // }
        // Store the parameter value
        super.transitions[StoredProcedureStatesEnum.PARAMETER_TYPE_STATE.ordinal()][UniversalTag.OCTET_STRING.getValue()] = 
            new GrammarTransition<StoredProcedureContainer>( StoredProcedureStatesEnum.PARAMETER_TYPE_STATE, 
                                    StoredProcedureStatesEnum.PARAMETER_VALUE_STATE, 
                                    UniversalTag.OCTET_STRING.getValue(),
                new GrammarAction<StoredProcedureContainer>( "Store parameter value" )
            {
                public void action( StoredProcedureContainer container ) throws DecoderException
                {
                    StoredProcedureContainer storedProcedureContainer = ( StoredProcedureContainer ) container;

                    TLV tlv = storedProcedureContainer.getCurrentTLV();
                    StoredProcedure storedProcedure = storedProcedureContainer.getStoredProcedure();

                    // Store the value.
                    if ( tlv.getLength() == 0 )
                    {
                        // We can't have a void parameter value !
                        String msg = I18n.err( I18n.ERR_04041 );
                        LOG.error( msg );
                        throw new DecoderException( msg );
                    }
                    else
                    {
                        byte[] parameterValue = tlv.getValue().getData();

                        if ( parameterValue.length != 0 )
                        {
                            StoredProcedureParameter parameter = storedProcedure.getCurrentParameter();
                            parameter.setValue( parameterValue );

                            // We can now add a new Parameter to the procedure
                            storedProcedure.addParameter( parameter );

                            if ( LOG.isDebugEnabled() )
                            {
                                LOG.debug( "Parameter value found : " + Strings.dumpBytes(parameterValue) );
                            }
                        }
                        else
                        {
                            String msg = I18n.err( I18n.ERR_04042 );
                            LOG.error( msg );
                            throw new DecoderException( msg );
                        }
                    }

                    // The only possible END state for the grammar is here
                    container.setGrammarEndAllowed( true );
                }
            } );
        
        // Parameters ::= SEQUENCE OF Parameter
        // 
        // Loop on next parameter
        super.transitions[StoredProcedureStatesEnum.PARAMETER_VALUE_STATE.ordinal()][UniversalTag.SEQUENCE.getValue()] = 
            new GrammarTransition<StoredProcedureContainer>( StoredProcedureStatesEnum.PARAMETER_VALUE_STATE, 
                                    StoredProcedureStatesEnum.PARAMETER_STATE, 
                                    UniversalTag.SEQUENCE.getValue(),
                                    null );
    }


    //~ Methods ------------------------------------------------------------------------------------

    /**
     * Get the instance of this grammar
     *
     * @return An instance on the StoredProcedure Grammar
     */
    public static StoredProcedureGrammar getInstance()
    {
        return instance;
    }
}
