/**
 *    Copyright 2011, Big Switch Networks, Inc.
 *    Originally created by David Erickson, Stanford University
 *
 *    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 net.onrc.onos.core.packet;

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

import org.apache.commons.lang.ArrayUtils;

// CHECKSTYLE IGNORE WriteTag FOR NEXT 2 LINES
/**
 * @author David Erickson (daviderickson@cs.stanford.edu)
 */
public class DHCP extends BasePacket {
    /**
     * ------------------------------------------
     * |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)               |
     * ------------------------------------------
     * Basic packet.
     */
    // 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(byte value) {
            this.value = value;
        }

        public byte getValue() {
            return 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 opCode;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @param clientHardwareAddress the clientHardwareAddress to set
     */
    public DHCP setClientHardwareAddress(byte[] clientHardwareAddress) {
        this.clientHardwareAddress = ArrayUtils.clone(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(DHCPOptionCode optionCode) {
        for (DHCPOption opt : options) {
            if (opt.code == optionCode.value) {
                return opt;
            }
        }
        return null;
    }

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

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

    /**
     * @return the packetType base on option 53
     */
    public DHCPPacketType getPacketType() {
        ListIterator<DHCPOption> lit = options.listIterator();
        while (lit.hasNext()) {
            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 serverName;
    }

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

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

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

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

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

        byte[] data = new byte[240 + optionsLength + optionsPadLength];
        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);
            }
        }
        writeString(this.serverName, bb, 64);
        writeString(this.bootFileName, bb, 128);
        // magic cookie
        bb.put((byte) 0x63);
        bb.put((byte) 0x82);
        bb.put((byte) 0x53);
        bb.put((byte) 0x63);
        for (DHCPOption option : this.options) {
            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(String string, ByteBuffer bb, 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 (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(byte[] data, int offset, int length) {
        ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
        if (bb.remaining() < 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();
        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 = readString(bb, 64);
        this.bootFileName = readString(bb, 128);
        // read the magic cookie
        // magic cookie
        bb.get();
        bb.get();
        bb.get();
        bb.get();
        // read options
        while (bb.hasRemaining()) {
            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()) {
                    int l = 0xff & bb.get(); // convert signed byte to int in range [0,255]
                    option.setLength((byte) l);
                    if (bb.remaining() >= l) {
                        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(ByteBuffer bb, int maxLength) {
        byte[] bytes = new byte[maxLength];
        bb.get(bytes);
        String result = null;
        try {
            result = new String(bytes, "ascii").trim();
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException("Failure decoding string", e);
        }
        return result;
    }
}
