/*
 * 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.service;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.util.Iterator;

import org.apache.directory.server.dhcp.DhcpException;
import org.apache.directory.server.dhcp.messages.DhcpMessage;
import org.apache.directory.server.dhcp.messages.MessageType;
import org.apache.directory.server.dhcp.options.DhcpOption;
import org.apache.directory.server.dhcp.options.OptionsField;
import org.apache.directory.server.dhcp.options.dhcp.ParameterRequestList;
import org.apache.directory.server.dhcp.options.dhcp.ServerIdentifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Abstract implementation of the server-side DHCP protocol. This class just
 * provides some utility methods and dispatches server-bound messages to handler
 * methods which can be overridden to provide the functionality.
 * <p>
 * Client-bound messages and BOOTP messages are ignored.
 * 
 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
 * @version $Rev: 545042 $, $Date: 2007-06-06 22:32:01 -0500 (Mi, 06 Jun 2007) $
 * 
 */
public abstract class AbstractDhcpService implements DhcpService {
    private static final Logger logger = LoggerFactory
            .getLogger(AbstractDhcpService.class);

    /*
     * @see org.apache.directory.server.dhcp.DhcpService#getReplyFor(org.apache.directory.server.dhcp.messages.DhcpMessage)
     */
    public final DhcpMessage getReplyFor(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        // ignore messages with an op != REQUEST/REPLY
        if (request.getOp() != DhcpMessage.OP_BOOTREQUEST
                && request.getOp() != DhcpMessage.OP_BOOTREPLY)
            return null;

        // message type option MUST be set - we don't support plain BOOTP.
        if (null == request.getMessageType()) {
            logger.warn("Missing message type option - plain BOOTP not supported.");
            return null;
        }

        // dispatch based on the message type
        switch (request.getMessageType().getCode()){
            // client-to-server messages
            case MessageType.CODE_DHCPDISCOVER :
                return handleDISCOVER(localAddress, clientAddress, request);
            case MessageType.CODE_DHCPREQUEST :
                return handleREQUEST(localAddress, clientAddress, request);
            case MessageType.CODE_DHCPRELEASE :
                return handleRELEASE(localAddress, clientAddress, request);
            case MessageType.CODE_DHCPINFORM :
                return handleINFORM(localAddress, clientAddress, request);

            case MessageType.CODE_DHCPOFFER :
                return handleOFFER(localAddress, clientAddress, request);

                // server-to-client messages
            case MessageType.CODE_DHCPDECLINE :
            case MessageType.CODE_DHCPACK :
            case MessageType.CODE_DHCPNAK :
                return null; // just ignore them

            default :
                return handleUnknownMessage(clientAddress, request);
        }
    }

    /**
     * Handle unknown DHCP message. The default implementation just logs and
     * ignores it.
     * 
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     */
    protected DhcpMessage handleUnknownMessage(InetSocketAddress clientAddress,
            DhcpMessage request) {
        if (logger.isWarnEnabled())
            logger.warn("Got unknkown DHCP message: " + request + " from:  "
                    + clientAddress);
        return null;
    }

    /**
     * Handle DHCPINFORM message. The default implementation just ignores it.
     * 
     * @param localAddress
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     */
    protected DhcpMessage handleINFORM(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        if (logger.isDebugEnabled())
            logger.debug("Got INFORM message: " + request + " from:  "
                    + clientAddress);
        return null;
    }

    /**
     * Handle DHCPRELEASE message. The default implementation just ignores it.
     * 
     * @param localAddress
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     */
    protected DhcpMessage handleRELEASE(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        if (logger.isDebugEnabled())
            logger.debug("Got RELEASE message: " + request + " from:  "
                    + clientAddress);
        return null;
    }

    /**
     * Handle DHCPREQUEST message. The default implementation just ignores it.
     * 
     * @param localAddress
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     */
    protected DhcpMessage handleREQUEST(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        if (logger.isDebugEnabled())
            logger.debug("Got REQUEST message: " + request + " from:  "
                    + clientAddress);
        return null;
    }

    /**
     * Handle DHCPDISCOVER message. The default implementation just ignores it.
     * 
     * @param localAddress
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     * @throws DhcpException
     */
    protected DhcpMessage handleDISCOVER(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        if (logger.isDebugEnabled())
            logger.debug("Got DISCOVER message: " + request + " from:  "
                    + clientAddress);
        return null;
    }

    /**
     * Handle DHCPOFFER message. The default implementation just ignores it.
     * 
     * @param localAddress
     * @param clientAddress
     * @param request the request message
     * @return DhcpMessage response message or <code>null</code> to ignore (don't reply to)
     *         it.
     * @throws DhcpException
     */
    protected DhcpMessage handleOFFER(InetSocketAddress localAddress,
            InetSocketAddress clientAddress, DhcpMessage request)
            throws DhcpException {
        if (logger.isDebugEnabled())
            logger
                    .debug("Got OFFER message: " + request + " from:  " + clientAddress);
        return null;
    }

    /**
     * Initialize a general DHCP reply message. Sets:
     * <ul>
     * <li>op=BOOTREPLY
     * <li>htype, hlen, xid, flags, giaddr, chaddr like in request message
     * <li>hops, secs to 0.
     * <li>server hostname to the hostname appropriate for the interface the
     * request was received on
     * <li>the server identifier set to the address of the interface the request
     * was received on
     * </ul>
     * 
     * @param localAddress
     * @param request
     * @return DhcpMessage
     */
    protected final DhcpMessage initGeneralReply(InetSocketAddress localAddress,
            DhcpMessage request) {
        final DhcpMessage reply = new DhcpMessage();

        reply.setOp(DhcpMessage.OP_BOOTREPLY);

        reply.setHardwareAddress(request.getHardwareAddress());
        reply.setTransactionId(request.getTransactionId());
        reply.setFlags(request.getFlags());
        reply.setRelayAgentAddress(request.getRelayAgentAddress());

        // set server hostname
        reply.setServerHostname(localAddress.getHostName());

        // set server identifier based on the IF on which we received the packet
        reply.getOptions().add(new ServerIdentifier(localAddress.getAddress()));

        return reply;
    }

    /**
     * Check if an address is the zero-address
     * 
     * @param addr
     * @return boolean
     */
    private boolean isZeroAddress(byte[] addr) {
        for (int i = 0; i < addr.length; i++)
            if (addr[i] != 0)
                return false;
        return true;
    }

    /**
     * Determine address on which to base selection. If the relay agent address is
     * set, we use the relay agent's address, otherwise we use the address we
     * received the request from.
     * 
     * @param clientAddress
     * @param request
     * @return InetAddress
     */
    protected final InetAddress determineSelectionBase(
            InetSocketAddress clientAddress, DhcpMessage request) {
        // FIXME: do we know
        // a) the interface address over which we received a message (!)
        // b) the client address (if specified)
        // c) the relay agent address?

        // if the relay agent address is set, we use it as the selection base
        if (!isZeroAddress(request.getRelayAgentAddress().getAddress()))
            return request.getRelayAgentAddress();

        return clientAddress.getAddress();
    }

    /**
     * Strip options that the client doesn't want, if the ParameterRequestList
     * option is present.
     * 
     * @param request
     * @param options
     */
    protected final void stripUnwantedOptions(DhcpMessage request,
            OptionsField options) {
        final ParameterRequestList prl = (ParameterRequestList) request
                .getOptions().get(ParameterRequestList.class);
        if (null != prl) {
            final byte[] list = prl.getData();
            for (final Iterator i = options.iterator(); i.hasNext();) {
                final DhcpOption o = (DhcpOption) i.next();
                for (int j = 0; j < list.length; j++)
                    if (list[j] == o.getTag())
                        continue;
                i.remove();
            }
        }
    }
}
