/*
 * Copyright 2014-present 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 com.google.common.collect.ImmutableMap;
import org.onlab.packet.dhcp.DhcpOption;
import org.onlab.packet.dhcp.DhcpRelayAgentOption;

import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import static com.google.common.base.Preconditions.checkArgument;
import static org.onlab.packet.PacketUtils.checkInput;
import static com.google.common.base.MoreObjects.toStringHelper;

/**
 * Representation of an DHCP Packet.
 */
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;

    private static final Map<Byte, Deserializer<? extends DhcpOption>> OPTION_DESERIALIZERS =
            ImmutableMap.of(DHCPOptionCode.OptionCode_CircuitID.value, DhcpRelayAgentOption.deserializer());
    private static final int UNSIGNED_BYTE_MASK = 0xff;
    private static final int BASE_OPTION_LEN = 60;
    private static final int MIN_DHCP_LEN = 240;
    private static final int BASE_HW_ADDR_LEN = 16;
    private static final byte PAD_BYTE = 0;
    private static final int BASE_SERVER_NAME_LEN = 64;
    private static final int BASE_BOOT_FILE_NAME_LEN = 128;
    private static final int MAGIC_COOKIE = 0x63825363;

    public enum DHCPOptionCode {
        OptionCode_Pad((byte) 0), OptionCode_SubnetMask((byte) 1),
        OptionCode_RouterAddress((byte) 3), OptionCode_DomainServer((byte) 6),
        OptionCode_HostName((byte) 12), OptionCode_DomainName((byte) 15),
        OptionCode_BroadcastAddress((byte) 28), 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_CircuitID((byte) 82),
        OptionCode_END((byte) 255);

        protected byte value;

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

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

    public enum MsgType {
        // From RFC 1533
        DHCPDISCOVER(1), DHCPOFFER(2), DHCPREQUEST(3), DHCPDECLINE(4), DHCPACK(5),
        DHCPNAK(6), DHCPRELEASE(7),

        // From RFC2132
        DHCPINFORM(8),

        // From RFC3203
        DHCPFORCERENEW(9),

        // From RFC4388
        DHCPLEASEQUERY(10), DHCPLEASEUNASSIGNED(11), DHCPLEASEUNKNOWN(12),
        DHCPLEASEACTIVE(13);

        protected int value;

        MsgType(final int value) {
            this.value = value;
        }

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

        public static MsgType getType(final int value) {
            switch (value) {
                case 1:
                    return DHCPDISCOVER;
                case 2:
                    return DHCPOFFER;
                case 3:
                    return DHCPREQUEST;
                case 4:
                    return DHCPDECLINE;
                case 5:
                    return DHCPACK;
                case 6:
                    return DHCPNAK;
                case 7:
                    return DHCPRELEASE;
                case 8:
                    return DHCPINFORM;
                case 9:
                    return DHCPFORCERENEW;
                case 10:
                    return DHCPLEASEQUERY;
                case 11:
                    return DHCPLEASEUNASSIGNED;
                case 12:
                    return DHCPLEASEUNKNOWN;
                case 13:
                    return DHCPLEASEACTIVE;
                default:
                    return null;
            }
        }
    }

    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.getCode() == optionCode.getValue()) {
                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 MsgType getPacketType() {
        return this.options.parallelStream()
                .filter(op -> op.getCode() == DHCPOptionCode.OptionCode_MessageType.getValue())
                .map(DhcpOption::getData)
                .filter(data -> data.length != 0)
                .map(data -> data[0])
                .map(MsgType::getType)
                .findFirst()
                .orElse(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() == DHCPOptionCode.OptionCode_Pad.getValue() ||
                    option.getCode() == DHCPOptionCode.OptionCode_END.getValue()) {
                optionsLength += 1;
            } else {
                optionsLength += 2 + (UNSIGNED_BYTE_MASK & option.getLength());
            }
        }
        int optionsPadLength = 0;
        if (optionsLength < BASE_OPTION_LEN) {
            optionsPadLength = BASE_OPTION_LEN - optionsLength;
        }

        final byte[] data = new byte[MIN_DHCP_LEN + 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);
        checkArgument(this.clientHardwareAddress.length <= BASE_HW_ADDR_LEN,
                "Hardware address is too long (%s bytes)", this.clientHardwareAddress.length);
        bb.put(this.clientHardwareAddress);
        if (this.clientHardwareAddress.length < BASE_HW_ADDR_LEN) {
            for (int i = 0; i < BASE_HW_ADDR_LEN - this.clientHardwareAddress.length; ++i) {
                bb.put(PAD_BYTE);
            }
        }
        this.writeString(this.serverName, bb, BASE_SERVER_NAME_LEN);
        this.writeString(this.bootFileName, bb, BASE_BOOT_FILE_NAME_LEN);
        // magic cookie
        bb.putInt(MAGIC_COOKIE);
        for (final DhcpOption option : this.options) {
            bb.put(option.serialize());
        }
        // assume the rest is padded out with zeroes
        return data;
    }

    @Override
    public IPacket deserialize(final byte[] data, final int offset,
                               final int length) {
        try {
            return deserializer().deserialize(data, offset, length);
        } catch (DeserializationException e) {
            return null;
        }
    }

    protected void writeString(final String string, final ByteBuffer bb,
            final int maxLength) {
        if (string == null) {
            for (int i = 0; i < maxLength; ++i) {
                bb.put(PAD_BYTE);
            }
        } else {
            byte[] bytes;
            bytes = string.getBytes(StandardCharsets.US_ASCII);
            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);
            }
        }
    }

    private static String readString(final ByteBuffer bb, final int maxLength) {
        final byte[] bytes = new byte[maxLength];
        bb.get(bytes);
        String result;
        result = new String(bytes, StandardCharsets.US_ASCII).trim();
        return result;
    }

    /**
     * Deserializer function for DHCP packets.
     *
     * @return deserializer function
     */
    public static Deserializer<DHCP> deserializer() {
        return (data, offset, length) -> {
            checkInput(data, offset, length, MIN_HEADER_LENGTH);

            ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
            DHCP dhcp = new DHCP();

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

            bb.get(dhcp.clientHardwareAddress);
            for (int i = hardwareAddressLength; i < BASE_HW_ADDR_LEN; ++i) {
                bb.get();
            }
            dhcp.serverName = readString(bb, BASE_SERVER_NAME_LEN);
            dhcp.bootFileName = readString(bb, BASE_BOOT_FILE_NAME_LEN);
            // read the magic cookie
            // magic cookie
            bb.getInt();

            // read options
            boolean foundEndOptionsMarker = false;
            while (bb.hasRemaining()) {
                DhcpOption option;
                int pos = bb.position();
                int optCode = UNSIGNED_BYTE_MASK & bb.array()[pos]; // to unsigned integer
                int optLen;
                byte[] optData;

                if (optCode == DHCPOptionCode.OptionCode_Pad.value) {
                    // pad, skip
                    // read option code
                    bb.get();
                    continue;
                }
                if (optCode == (UNSIGNED_BYTE_MASK & DHCPOptionCode.OptionCode_END.value)) {
                    // end of dhcp options or invalid option and set the END option
                    option = new DhcpOption();
                    option.setCode((byte) optCode);
                    dhcp.options.add(option);
                    foundEndOptionsMarker = true;
                    break;
                }

                if (bb.remaining() < 2) {
                    // No option length
                    throw new DeserializationException("Buffer underflow while reading DHCP option");
                }

                optLen = UNSIGNED_BYTE_MASK & bb.array()[pos + 1];
                if (bb.remaining() < DhcpOption.DEFAULT_LEN + optLen) {
                    // Invalid option length
                    throw new DeserializationException("Buffer underflow while reading DHCP option");
                }
                optData = new byte[DhcpOption.DEFAULT_LEN + optLen];
                bb.get(optData);
                if (OPTION_DESERIALIZERS.containsKey((byte) optCode)) {
                    option = OPTION_DESERIALIZERS.get((byte) optCode).deserialize(optData, 0, optData.length);
                    dhcp.options.add(option);
                } else {
                    // default option
                    option = DhcpOption.deserializer().deserialize(optData, 0, optData.length);
                    dhcp.options.add(option);
                }
            }

            if (!foundEndOptionsMarker) {
                throw new DeserializationException("DHCP End options marker was missing");
            }

            return dhcp;
        };
    }

    @Override
    public String toString() {
        return toStringHelper(getClass())
                .add("opCode", Byte.toString(opCode))
                .add("hardwareType", Byte.toString(hardwareType))
                .add("hardwareAddressLength", Byte.toString(hardwareAddressLength))
                .add("hops", Byte.toString(hops))
                .add("transactionId", Integer.toString(transactionId))
                .add("seconds", Short.toString(seconds))
                .add("flags", Short.toString(flags))
                .add("clientIPAddress", Integer.toString(clientIPAddress))
                .add("yourIPAddress", Integer.toString(yourIPAddress))
                .add("serverIPAddress", Integer.toString(serverIPAddress))
                .add("gatewayIPAddress", Integer.toString(gatewayIPAddress))
                .add("clientHardwareAddress", Arrays.toString(clientHardwareAddress))
                .add("serverName", serverName)
                .add("bootFileName", bootFileName)
                .toString();
        // TODO: need to handle options
    }
}
