/*
 *   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.server.ldap;


import org.apache.directory.api.ldap.codec.api.LdapApiServiceFactory;
import org.apache.directory.api.ldap.codec.api.LdapDecoder;
import org.apache.directory.api.ldap.codec.api.LdapMessageContainer;
import org.apache.directory.api.ldap.codec.api.MessageDecorator;
import org.apache.directory.api.ldap.codec.api.SchemaBinaryAttributeDetector;
import org.apache.directory.api.ldap.model.exception.ResponseCarryingMessageException;
import org.apache.directory.api.ldap.model.message.Control;
import org.apache.directory.api.ldap.model.message.ExtendedRequest;
import org.apache.directory.api.ldap.model.message.Message;
import org.apache.directory.api.ldap.model.message.Request;
import org.apache.directory.api.ldap.model.message.ResultCodeEnum;
import org.apache.directory.api.ldap.model.message.ResultResponse;
import org.apache.directory.api.ldap.model.message.ResultResponseRequest;
import org.apache.directory.api.ldap.model.message.extended.NoticeOfDisconnect;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.ssl.SslFilter;
import org.apache.mina.handler.demux.DemuxingIoHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * The MINA IoHandler implementation extending {@link DemuxingIoHandler} for
 * the LDAP protocol.  THe {@link LdapServer} creates this multiplexing
 * {@link IoHandler} handler and populates it with subordinate handlers for
 * the various kinds of LDAP {@link Request} messages.  This is done in the
 * setXxxHandler() methods of the LdapServer where Xxxx is Add, Modify, etc.
 *
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
class LdapProtocolHandler extends DemuxingIoHandler
{
    /** The logger */
    private static final Logger LOG = LoggerFactory.getLogger( LdapProtocolHandler.class );

    /** the {@link LdapServer} this handler is associated with */
    private final LdapServer ldapServer;


    /**
     * Creates a new instance of LdapProtocolHandler.
     *
     * @param ldapServer The LDAP server instance
     */
    LdapProtocolHandler( LdapServer ldapServer )
    {
        this.ldapServer = ldapServer;
    }


    /**
     * This method is called when a new session is created. We will store some
     * informations that the session will need to process incoming requests.
     * 
     * @param session the newly created session
     */
    public void sessionCreated( IoSession session ) throws Exception
    {
        // First, create a new LdapSession and store it i the manager
        LdapSession ldapSession = new LdapSession( session );
        ldapServer.getLdapSessionManager().addLdapSession( ldapSession );

        // Now, we have to store the DirectoryService instance into the session
        session.setAttribute( LdapDecoder.MAX_PDU_SIZE_ATTR, ldapServer.getDirectoryService().getMaxPDUSize() );

        // Last, store the message container
        LdapMessageContainer<? extends MessageDecorator<Message>> ldapMessageContainer =
            new LdapMessageContainer<MessageDecorator<Message>>(
                ldapServer.getDirectoryService().getLdapCodecService(),
                new SchemaBinaryAttributeDetector(
                    ldapServer.getDirectoryService().getSchemaManager() ) );

        session.setAttribute( LdapDecoder.MESSAGE_CONTAINER_ATTR, ldapMessageContainer );
    }


    /**
     * This method is called when a session is closed. If we have some
     * cleanup to do, it's done there.
     * 
     * @param session the closing session
     */
    public void sessionClosed( IoSession session )
    {
        // Get the associated LdapSession
        LdapSession ldapSession = ldapServer.getLdapSessionManager().removeLdapSession( session );

        // Clean it up !
        cleanUpSession( ldapSession );
    }


    /**
     * Explicitly handles {@link LdapSession} and {@link IoSession} cleanup tasks.
     *
     * @param ldapSession the LdapSession to cleanup after being removed from
     * the {@link LdapSessionManager}
     */
    private void cleanUpSession( LdapSession ldapSession )
    {
        if ( ldapSession == null )
        {
            LOG.debug( "Null LdapSession given to cleanUpSession." );
            return;
        }

        LOG.debug( "Cleaning the {} session", ldapSession );

        // Abandon all the requests
        ldapSession.abandonAllOutstandingRequests();

        if ( !ldapSession.getIoSession().isClosing() || ldapSession.getIoSession().isConnected() )
        {
            try
            {
                ldapSession.getIoSession().close( true );
            }
            catch ( Throwable t )
            {
                LOG.warn( "Failed to close IoSession for LdapSession." );
            }
        }
    }


    /**
     * {@inheritDoc}
     */
    public void messageSent( IoSession session, Object message ) throws Exception
    {
        // Do nothing : we have to ignore this message, otherwise we get an exception,
        // thanks to the way MINA 2 works ...
        if ( message instanceof IoBuffer )
        {
            // Nothing to do in this case
            return;
        }

        super.messageSent( session, message );
    }


    /**
     * {@inheritDoc}
     */
    public void messageReceived( IoSession session, Object message ) throws Exception
    {
        // Translate SSLFilter messages into LDAP extended request
        // defined in RFC #2830, 'Lightweight Directory Access Protocol (v3):
        // Extension for Transport Layer Security'.
        //
        // The RFC specifies the payload should be empty, but we use
        // it to notify the TLS state changes.  This hack should be
        // OK from the viewpointd of security because StartTLS
        // handler should react to only SESSION_UNSECURED message
        // and degrade authentication level to 'anonymous' as specified
        // in the RFC, and this is no threat.

        if ( message == SslFilter.SESSION_SECURED )
        {
            ExtendedRequest req =
                LdapApiServiceFactory.getSingleton().newExtendedRequest( "1.3.6.1.4.1.1466.20037",
                    "SECURED".getBytes( "ISO-8859-1" ) );
            message = req;
        }
        else if ( message == SslFilter.SESSION_UNSECURED )
        {
            ExtendedRequest req =
                LdapApiServiceFactory.getSingleton().newExtendedRequest( "1.3.6.1.4.1.1466.20037",
                    "SECURED".getBytes( "ISO-8859-1" ) );
            message = req;
        }

        if ( ( ( Request ) message ).getControls().size() > 0
            && message instanceof ResultResponseRequest )
        {
            ResultResponseRequest req = ( ResultResponseRequest ) message;

            for ( Control control : req.getControls().values() )
            {
                if ( control.isCritical() && !ldapServer.getSupportedControls().contains( control.getOid() ) )
                {
                    ResultResponse resp = req.getResultResponse();
                    resp.getLdapResult().setDiagnosticMessage( "Unsupport critical control: " + control.getOid() );
                    resp.getLdapResult().setResultCode( ResultCodeEnum.UNAVAILABLE_CRITICAL_EXTENSION );
                    session.write( resp );

                    return;
                }
            }
        }

        super.messageReceived( session, message );
    }


    /**
     * {@inheritDoc}
     */
    public void exceptionCaught( IoSession session, Throwable cause )
    {
        if ( cause.getCause() instanceof ResponseCarryingMessageException )
        {
            ResponseCarryingMessageException rcme = ( ResponseCarryingMessageException ) cause.getCause();

            if ( rcme.getResponse() != null )
            {
                session.write( rcme.getResponse() );
                return;
            }
        }

        LOG.warn( "Unexpected exception forcing session to close: sending disconnect notice to client.", cause );

        session.write( NoticeOfDisconnect.PROTOCOLERROR );
        LdapSession ldapSession = this.ldapServer.getLdapSessionManager().removeLdapSession( session );
        cleanUpSession( ldapSession );
        session.close( true );
    }
}
