/*
 *  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.dhcp.protocol;


import java.net.InetAddress;
import java.net.InetSocketAddress;

import org.apache.directory.server.dhcp.messages.DhcpMessage;
import org.apache.directory.server.dhcp.messages.MessageType;
import org.apache.directory.server.dhcp.service.DhcpService;
import org.apache.mina.core.service.IoHandler;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.ProtocolCodecFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * Implementation of a DHCP protocol handler which delegates the work of
 * generating replys to a DhcpService implementation.
 * 
 * @see org.apache.directory.server.dhcp.service.DhcpService
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 */
public class DhcpProtocolHandler implements IoHandler
{
    private static final Logger logger = LoggerFactory
        .getLogger( DhcpProtocolHandler.class );

    /**
     * Default DHCP client port
     */
    public static final int CLIENT_PORT = 68;

    /**
     * Default DHCP server port
     */
    public static final int SERVER_PORT = 67;

    /**
     * The DHCP service implementation. The implementation is supposed to be
     * thread-safe.
     */
    private final DhcpService dhcpService;


    /**
     * 
     */
    public DhcpProtocolHandler( DhcpService service )
    {
        this.dhcpService = service;
    }


    public void sessionCreated( IoSession session ) throws Exception
    {
        logger.debug( "{} CREATED", session.getLocalAddress() );
        session.getFilterChain().addFirst( "codec",
            new ProtocolCodecFilter( new DhcpProtocolCodecFactory() ) );
    }


    public void sessionOpened( IoSession session )
    {
        logger.debug( "{} -> {} OPENED", session.getRemoteAddress(), session
            .getLocalAddress() );
    }


    public void sessionClosed( IoSession session )
    {
        logger.debug( "{} -> {} CLOSED", session.getRemoteAddress(), session
            .getLocalAddress() );
    }


    public void sessionIdle( IoSession session, IdleStatus status )
    {
        // ignore
    }


    public void exceptionCaught( IoSession session, Throwable cause )
    {
        logger.error( "EXCEPTION CAUGHT ", cause );
        cause.printStackTrace( System.out );

        session.close( true );
    }


    public void messageReceived( IoSession session, Object message )
        throws Exception
    {
        if ( logger.isDebugEnabled() )
        {
            logger.debug( "{} -> {} RCVD: {} " + message, session.getRemoteAddress(),
                session.getLocalAddress() );
        }

        final DhcpMessage request = ( DhcpMessage ) message;

        final DhcpMessage reply = dhcpService.getReplyFor(
            ( InetSocketAddress ) session.getServiceAddress(),
            ( InetSocketAddress ) session.getRemoteAddress(), request );

        if ( null != reply )
        {
            final InetSocketAddress isa = determineMessageDestination( request, reply );
            session.write( reply, isa );
        }
    }


    /**
     * Determine where to send the message: <br>
     * If the 'giaddr' field in a DHCP message from a client is non-zero, the
     * server sends any return messages to the 'DHCP server' port on the BOOTP
     * relay agent whose address appears in 'giaddr'. If the 'giaddr' field is
     * zero and the 'ciaddr' field is nonzero, then the server unicasts DHCPOFFER
     * and DHCPACK messages to the address in 'ciaddr'. If 'giaddr' is zero and
     * 'ciaddr' is zero, and the broadcast bit is set, then the server broadcasts
     * DHCPOFFER and DHCPACK messages to 0xffffffff. If the broadcast bit is not
     * set and 'giaddr' is zero and 'ciaddr' is zero, then the server unicasts
     * DHCPOFFER and DHCPACK messages to the client's hardware address and
     * 'yiaddr' address. In all cases, when 'giaddr' is zero, the server
     * broadcasts any DHCPNAK messages to 0xffffffff.
     * 
     * @param request
     * @param reply
     * @return
     */
    //This will suppress PMD.AvoidUsingHardCodedIP warnings in this class
    @SuppressWarnings("PMD.AvoidUsingHardCodedIP")
    private InetSocketAddress determineMessageDestination( DhcpMessage request,
        DhcpMessage reply )
    {

        final MessageType mt = reply.getMessageType();

        if ( !isNullAddress( request.getRelayAgentAddress() ) )
        {
            // send to agent, if received via agent.
            return new InetSocketAddress( request.getRelayAgentAddress(), SERVER_PORT );
        }
        else if ( null != mt && mt == MessageType.DHCPNAK )
        {
            // force broadcast for DHCPNAKs
            return new InetSocketAddress( "255.255.255.255", 68 );
        }
        else
        {
            // not a NAK...
            if ( !isNullAddress( request.getCurrentClientAddress() ) )
            {
                // have a current address? unicast to it.
                return new InetSocketAddress( request.getCurrentClientAddress(),
                    CLIENT_PORT );
            }
            else
            {
                return new InetSocketAddress( "255.255.255.255", 68 );
            }
        }
    }


    /**
     * Determine, whether the given address ist actually the null address
     * "0.0.0.0".
     * 
     * @param relayAgentAddress
     * @return
     */
    private boolean isNullAddress( InetAddress addr )
    {
        final byte a[] = addr.getAddress();

        for ( int i = 0; i < a.length; i++ )
        {
            if ( a[i] != 0 )
            {
                return false;
            }
        }

        return true;
    }


    public void messageSent( IoSession session, Object message )
    {
        if ( logger.isDebugEnabled() )
        {
            logger.debug( "{} -> {} SENT: " + message, session.getRemoteAddress(),
                session.getLocalAddress() );
        }
    }
    
    public void inputClosed( IoSession session )
    {
    }
}
