/*
 * Copyright 2014 Open Networking Laboratory
 *
 * Licensed 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.onlab.packet;

import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;

/**
 *
 */
public class DHCP extends BasePacket {
    /**
     * Dynamic Host Configuration Protocol packet.
     * ------------------------------------------ |op (1) | htype(1) | hlen(1) |
     * hops(1) | ------------------------------------------ | xid (4) |
     * ------------------------------------------ | secs (2) | flags (2) |
     * ------------------------------------------ | ciaddr (4) |
     * ------------------------------------------ | yiaddr (4) |
     * ------------------------------------------ | siaddr (4) |
     * ------------------------------------------ | giaddr (4) |
     * ------------------------------------------ | chaddr (16) |
     * ------------------------------------------ | sname (64) |
     * ------------------------------------------ | file (128) |
     * ------------------------------------------ | options (312) |
     * ------------------------------------------
     *
     */
    // Header + magic without options
    public static final int MIN_HEADER_LENGTH = 240;
    public static final byte OPCODE_REQUEST = 0x1;
    public static final byte OPCODE_REPLY = 0x2;

    public static final byte HWTYPE_ETHERNET = 0x1;

    public enum DHCPOptionCode {
        OptionCode_SubnetMask((byte) 1), OptionCode_RequestedIP((byte) 50), OptionCode_LeaseTime(
                (byte) 51), OptionCode_MessageType((byte) 53), OptionCode_DHCPServerIp(
                        (byte) 54), OptionCode_RequestedParameters((byte) 55), OptionCode_RenewalTime(
                                (byte) 58), OPtionCode_RebindingTime((byte) 59), OptionCode_ClientID(
                                        (byte) 61), OptionCode_END((byte) 255);

        protected byte value;

        private DHCPOptionCode(final byte value) {
            this.value = value;
        }

        public byte getValue() {
            return this.value;
        }
    }

    protected byte opCode;
    protected byte hardwareType;
    protected byte hardwareAddressLength;
    protected byte hops;
    protected int transactionId;
    protected short seconds;
    protected short flags;
    protected int clientIPAddress;
    protected int yourIPAddress;
    protected int serverIPAddress;
    protected int gatewayIPAddress;
    protected byte[] clientHardwareAddress;
    protected String serverName;
    protected String bootFileName;
    protected List<DHCPOption> options = new ArrayList<DHCPOption>();

    /**
     * @return the opCode
     */
    public byte getOpCode() {
        return this.opCode;
    }

    /**
     * @param opCode
     *            the opCode to set
     * @return this
     */
    public DHCP setOpCode(final byte opCode) {
        this.opCode = opCode;
        return this;
    }

    /**
     * @return the hardwareType
     */
    public byte getHardwareType() {
        return this.hardwareType;
    }

    /**
     * @param hardwareType
     *            the hardwareType to set
     * @return this
     */
    public DHCP setHardwareType(final byte hardwareType) {
        this.hardwareType = hardwareType;
        return this;
    }

    /**
     * @return the hardwareAddressLength
     */
    public byte getHardwareAddressLength() {
        return this.hardwareAddressLength;
    }

    /**
     * @param hardwareAddressLength
     *            the hardwareAddressLength to set
     * @return this
     */
    public DHCP setHardwareAddressLength(final byte hardwareAddressLength) {
        this.hardwareAddressLength = hardwareAddressLength;
        return this;
    }

    /**
     * @return the hops
     */
    public byte getHops() {
        return this.hops;
    }

    /**
     * @param hops
     *            the hops to set
     * @return this
     */
    public DHCP setHops(final byte hops) {
        this.hops = hops;
        return this;
    }

    /**
     * @return the transactionId
     */
    public int getTransactionId() {
        return this.transactionId;
    }

    /**
     * @param transactionId
     *            the transactionId to set
     * @return this
     */
    public DHCP setTransactionId(final int transactionId) {
        this.transactionId = transactionId;
        return this;
    }

    /**
     * @return the seconds
     */
    public short getSeconds() {
        return this.seconds;
    }

    /**
     * @param seconds
     *            the seconds to set
     * @return this
     */
    public DHCP setSeconds(final short seconds) {
        this.seconds = seconds;
        return this;
    }

    /**
     * @return the flags
     */
    public short getFlags() {
        return this.flags;
    }

    /**
     * @param flags
     *            the flags to set
     * @return this
     */
    public DHCP setFlags(final short flags) {
        this.flags = flags;
        return this;
    }

    /**
     * @return the clientIPAddress
     */
    public int getClientIPAddress() {
        return this.clientIPAddress;
    }

    /**
     * @param clientIPAddress
     *            the clientIPAddress to set
     * @return this
     */
    public DHCP setClientIPAddress(final int clientIPAddress) {
        this.clientIPAddress = clientIPAddress;
        return this;
    }

    /**
     * @return the yourIPAddress
     */
    public int getYourIPAddress() {
        return this.yourIPAddress;
    }

    /**
     * @param yourIPAddress
     *            the yourIPAddress to set
     * @return this
     */
    public DHCP setYourIPAddress(final int yourIPAddress) {
        this.yourIPAddress = yourIPAddress;
        return this;
    }

    /**
     * @return the serverIPAddress
     */
    public int getServerIPAddress() {
        return this.serverIPAddress;
    }

    /**
     * @param serverIPAddress
     *            the serverIPAddress to set
     * @return this
     */
    public DHCP setServerIPAddress(final int serverIPAddress) {
        this.serverIPAddress = serverIPAddress;
        return this;
    }

    /**
     * @return the gatewayIPAddress
     */
    public int getGatewayIPAddress() {
        return this.gatewayIPAddress;
    }

    /**
     * @param gatewayIPAddress
     *            the gatewayIPAddress to set
     * @return this
     */
    public DHCP setGatewayIPAddress(final int gatewayIPAddress) {
        this.gatewayIPAddress = gatewayIPAddress;
        return this;
    }

    /**
     * @return the clientHardwareAddress
     */
    public byte[] getClientHardwareAddress() {
        return this.clientHardwareAddress;
    }

    /**
     * @param clientHardwareAddress
     *            the clientHardwareAddress to set
     * @return this
     */
    public DHCP setClientHardwareAddress(final byte[] clientHardwareAddress) {
        this.clientHardwareAddress = clientHardwareAddress;
        return this;
    }

    /**
     * Gets a specific DHCP option parameter.
     *
     * @param optionCode
     *            The option code to get
     * @return The value of the option if it exists, null otherwise
     */
    public DHCPOption getOption(final DHCPOptionCode optionCode) {
        for (final DHCPOption opt : this.options) {
            if (opt.code == optionCode.value) {
                return opt;
            }
        }
        return null;
    }

    /**
     * @return the options
     */
    public List<DHCPOption> getOptions() {
        return this.options;
    }

    /**
     * @param options
     *            the options to set
     * @return this
     */
    public DHCP setOptions(final List<DHCPOption> options) {
        this.options = options;
        return this;
    }

    /**
     * @return the packetType base on option 53
     */
    public DHCPPacketType getPacketType() {
        final ListIterator<DHCPOption> lit = this.options.listIterator();
        while (lit.hasNext()) {
            final DHCPOption option = lit.next();
            // only care option 53
            if (option.getCode() == 53) {
                return DHCPPacketType.getType(option.getData()[0]);
            }
        }
        return null;
    }

    /**
     * @return the serverName
     */
    public String getServerName() {
        return this.serverName;
    }

    /**
     * @param server
     *            the serverName to set
     * @return this
     */
    public DHCP setServerName(final String server) {
        this.serverName = server;
        return this;
    }

    /**
     * @return the bootFileName
     */
    public String getBootFileName() {
        return this.bootFileName;
    }

    /**
     * @param bootFile
     *            the bootFileName to set
     * @return this
     */
    public DHCP setBootFileName(final String bootFile) {
        this.bootFileName = bootFile;
        return this;
    }

    @Override
    public byte[] serialize() {
        // not guaranteed to retain length/exact format
        this.resetChecksum();

        // minimum size 240 including magic cookie, options generally padded to
        // 300
        int optionsLength = 0;
        for (final DHCPOption option : this.options) {
            if (option.getCode() == 0 || option.getCode() == ((byte) 255)) {
                optionsLength += 1;
            } else {
                optionsLength += 2 + (0xff & option.getLength());
            }
        }
        int optionsPadLength = 0;
        if (optionsLength < 60) {
            optionsPadLength = 60 - optionsLength;
        }

        final byte[] data = new byte[240 + optionsLength + optionsPadLength];
        final ByteBuffer bb = ByteBuffer.wrap(data);
        bb.put(this.opCode);
        bb.put(this.hardwareType);
        bb.put(this.hardwareAddressLength);
        bb.put(this.hops);
        bb.putInt(this.transactionId);
        bb.putShort(this.seconds);
        bb.putShort(this.flags);
        bb.putInt(this.clientIPAddress);
        bb.putInt(this.yourIPAddress);
        bb.putInt(this.serverIPAddress);
        bb.putInt(this.gatewayIPAddress);
        bb.put(this.clientHardwareAddress);
        if (this.clientHardwareAddress.length < 16) {
            for (int i = 0; i < 16 - this.clientHardwareAddress.length; ++i) {
                bb.put((byte) 0x0);
            }
        }
        this.writeString(this.serverName, bb, 64);
        this.writeString(this.bootFileName, bb, 128);
        // magic cookie
        bb.put((byte) 0x63);
        bb.put((byte) 0x82);
        bb.put((byte) 0x53);
        bb.put((byte) 0x63);
        for (final DHCPOption option : this.options) {
            final int code = option.getCode() & 0xff;
            bb.put((byte) code);
            if (code != 0 && code != 255) {
                bb.put(option.getLength());
                bb.put(option.getData());
            }
        }
        // assume the rest is padded out with zeroes
        return data;
    }

    protected void writeString(final String string, final ByteBuffer bb,
            final int maxLength) {
        if (string == null) {
            for (int i = 0; i < maxLength; ++i) {
                bb.put((byte) 0x0);
            }
        } else {
            byte[] bytes = null;
            try {
                bytes = string.getBytes("ascii");
            } catch (final UnsupportedEncodingException e) {
                throw new RuntimeException("Failure encoding server name", e);
            }
            int writeLength = bytes.length;
            if (writeLength > maxLength) {
                writeLength = maxLength;
            }
            bb.put(bytes, 0, writeLength);
            for (int i = writeLength; i < maxLength; ++i) {
                bb.put((byte) 0x0);
            }
        }
    }

    @Override
    public IPacket deserialize(final byte[] data, final int offset,
            final int length) {
        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
        if (bb.remaining() < DHCP.MIN_HEADER_LENGTH) {
            return this;
        }

        this.opCode = bb.get();
        this.hardwareType = bb.get();
        this.hardwareAddressLength = bb.get();
        this.hops = bb.get();
        this.transactionId = bb.getInt();
        this.seconds = bb.getShort();
        this.flags = bb.getShort();
        this.clientIPAddress = bb.getInt();
        this.yourIPAddress = bb.getInt();
        this.serverIPAddress = bb.getInt();
        this.gatewayIPAddress = bb.getInt();
        final int hardwareAddressLength = 0xff & this.hardwareAddressLength;
        this.clientHardwareAddress = new byte[hardwareAddressLength];

        bb.get(this.clientHardwareAddress);
        for (int i = hardwareAddressLength; i < 16; ++i) {
            bb.get();
        }
        this.serverName = this.readString(bb, 64);
        this.bootFileName = this.readString(bb, 128);
        // read the magic cookie
        // magic cookie
        bb.get();
        bb.get();
        bb.get();
        bb.get();
        // read options
        while (bb.hasRemaining()) {
            final DHCPOption option = new DHCPOption();
            int code = 0xff & bb.get(); // convert signed byte to int in range
            // [0,255]
            option.setCode((byte) code);
            if (code == 0) {
                // skip these
                continue;
            } else if (code != 255) {
                if (bb.hasRemaining()) {
                    final int l = 0xff & bb.get(); // convert signed byte to
                    // int in range [0,255]
                    option.setLength((byte) l);
                    if (bb.remaining() >= l) {
                        final byte[] optionData = new byte[l];
                        bb.get(optionData);
                        option.setData(optionData);
                    } else {
                        // Skip the invalid option and set the END option
                        code = 0xff;
                        option.setCode((byte) code);
                        option.setLength((byte) 0);
                    }
                } else {
                    // Skip the invalid option and set the END option
                    code = 0xff;
                    option.setCode((byte) code);
                    option.setLength((byte) 0);
                }
            }
            this.options.add(option);
            if (code == 255) {
                // remaining bytes are supposed to be 0, but ignore them just in
                // case
                break;
            }
        }

        return this;
    }

    protected String readString(final ByteBuffer bb, final int maxLength) {
        final byte[] bytes = new byte[maxLength];
        bb.get(bytes);
        String result = null;
        try {
            result = new String(bytes, "ascii").trim();
        } catch (final UnsupportedEncodingException e) {
            throw new RuntimeException("Failure decoding string", e);
        }
        return result;
    }
}
