/*
 * Copyright 2014-present Open Networking Foundation
 *
 * 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.nio.ByteBuffer;
import java.util.Arrays;

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

/**
 * Representation of an ARP Packet.
 */
public class ARP extends BasePacket {
    public static final short HW_TYPE_ETHERNET = 0x1;

    public static final short PROTO_TYPE_IP = 0x800;

    public static final short OP_REQUEST = 0x1;
    public static final short OP_REPLY = 0x2;
    public static final short OP_RARP_REQUEST = 0x3;
    public static final short OP_RARP_REPLY = 0x4;

    public static final short INITIAL_HEADER_LENGTH = 8;

    protected short hardwareType;
    protected short protocolType;
    protected byte hardwareAddressLength;
    protected byte protocolAddressLength;
    protected short opCode;
    protected byte[] senderHardwareAddress;
    protected byte[] senderProtocolAddress;
    protected byte[] targetHardwareAddress;
    protected byte[] targetProtocolAddress;

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

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

    /**
     * @return the protocolType
     */
    public short getProtocolType() {
        return this.protocolType;
    }

    /**
     * @param protoType
     *            the protocolType to set
     * @return this
     */
    public ARP setProtocolType(final short protoType) {
        this.protocolType = protoType;
        return this;
    }

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

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

    /**
     * @return the protocolAddressLength
     */
    public byte getProtocolAddressLength() {
        return this.protocolAddressLength;
    }

    /**
     * @param protoAddressLength
     *            the protocolAddressLength to set
     * @return this
     */
    public ARP setProtocolAddressLength(final byte protoAddressLength) {
        this.protocolAddressLength = protoAddressLength;
        return this;
    }

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

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

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

    /**
     * @param senderHWAddress
     *            the senderHardwareAddress to set
     * @return this
     */
    public ARP setSenderHardwareAddress(final byte[] senderHWAddress) {
        this.senderHardwareAddress = senderHWAddress;
        return this;
    }

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

    /**
     * @param senderProtoAddress
     *            the senderProtocolAddress to set
     * @return this
     */
    public ARP setSenderProtocolAddress(final byte[] senderProtoAddress) {
        this.senderProtocolAddress = senderProtoAddress;
        return this;
    }

    public ARP setSenderProtocolAddress(final int address) {
        this.senderProtocolAddress = ByteBuffer.allocate(4).putInt(address)
                .array();
        return this;
    }

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

    /**
     * @param targetHWAddress
     *            the targetHardwareAddress to set
     * @return this
     */
    public ARP setTargetHardwareAddress(final byte[] targetHWAddress) {
        this.targetHardwareAddress = targetHWAddress;
        return this;
    }

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

    /**
     * @return True if gratuitous ARP (SPA = TPA), false otherwise
     */
    public boolean isGratuitous() {
        assert this.senderProtocolAddress.length == this.targetProtocolAddress.length;

        int indx = 0;
        while (indx < this.senderProtocolAddress.length) {
            if (this.senderProtocolAddress[indx] != this.targetProtocolAddress[indx]) {
                return false;
            }
            indx++;
        }

        return true;
    }

    /**
     * @param targetProtoAddress
     *            the targetProtocolAddress to set
     * @return this
     */
    public ARP setTargetProtocolAddress(final byte[] targetProtoAddress) {
        this.targetProtocolAddress = targetProtoAddress;
        return this;
    }

    public ARP setTargetProtocolAddress(final int address) {
        this.targetProtocolAddress = ByteBuffer.allocate(4).putInt(address)
                .array();
        return this;
    }

    @Override
    public byte[] serialize() {
        final int length = 8 + 2 * (0xff & this.hardwareAddressLength) + 2
                * (0xff & this.protocolAddressLength);
        final byte[] data = new byte[length];
        final ByteBuffer bb = ByteBuffer.wrap(data);
        bb.putShort(this.hardwareType);
        bb.putShort(this.protocolType);
        bb.put(this.hardwareAddressLength);
        bb.put(this.protocolAddressLength);
        bb.putShort(this.opCode);
        bb.put(this.senderHardwareAddress, 0, 0xff & this.hardwareAddressLength);
        bb.put(this.senderProtocolAddress, 0, 0xff & this.protocolAddressLength);
        bb.put(this.targetHardwareAddress, 0, 0xff & this.hardwareAddressLength);
        bb.put(this.targetProtocolAddress, 0, 0xff & this.protocolAddressLength);
        return data;
    }

    @Override
    public IPacket deserialize(final byte[] data, final int offset,
                               final int length) {
        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
        this.hardwareType = bb.getShort();
        this.protocolType = bb.getShort();
        this.hardwareAddressLength = bb.get();
        this.protocolAddressLength = bb.get();
        this.opCode = bb.getShort();
        this.senderHardwareAddress = new byte[0xff & this.hardwareAddressLength];
        bb.get(this.senderHardwareAddress, 0, this.senderHardwareAddress.length);
        this.senderProtocolAddress = new byte[0xff & this.protocolAddressLength];
        bb.get(this.senderProtocolAddress, 0, this.senderProtocolAddress.length);
        this.targetHardwareAddress = new byte[0xff & this.hardwareAddressLength];
        bb.get(this.targetHardwareAddress, 0, this.targetHardwareAddress.length);
        this.targetProtocolAddress = new byte[0xff & this.protocolAddressLength];
        bb.get(this.targetProtocolAddress, 0, this.targetProtocolAddress.length);
        return this;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 13121;
        int result = super.hashCode();
        result = prime * result + this.hardwareAddressLength;
        result = prime * result + this.hardwareType;
        result = prime * result + this.opCode;
        result = prime * result + this.protocolAddressLength;
        result = prime * result + this.protocolType;
        result = prime * result + Arrays.hashCode(this.senderHardwareAddress);
        result = prime * result + Arrays.hashCode(this.senderProtocolAddress);
        result = prime * result + Arrays.hashCode(this.targetHardwareAddress);
        result = prime * result + Arrays.hashCode(this.targetProtocolAddress);
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (!super.equals(obj)) {
            return false;
        }
        if (!(obj instanceof ARP)) {
            return false;
        }
        final ARP other = (ARP) obj;
        if (this.hardwareAddressLength != other.hardwareAddressLength) {
            return false;
        }
        if (this.hardwareType != other.hardwareType) {
            return false;
        }
        if (this.opCode != other.opCode) {
            return false;
        }
        if (this.protocolAddressLength != other.protocolAddressLength) {
            return false;
        }
        if (this.protocolType != other.protocolType) {
            return false;
        }
        if (!Arrays.equals(this.senderHardwareAddress,
                other.senderHardwareAddress)) {
            return false;
        }
        if (!Arrays.equals(this.senderProtocolAddress,
                other.senderProtocolAddress)) {
            return false;
        }
        if (!Arrays.equals(this.targetHardwareAddress,
                other.targetHardwareAddress)) {
            return false;
        }
        if (!Arrays.equals(this.targetProtocolAddress,
                other.targetProtocolAddress)) {
            return false;
        }
        return true;
    }

    /**
     * Builds an ARP request using the supplied parameters.
     *
     * @param senderMacAddress the mac address of the sender
     * @param senderIpAddress the ip address of the sender
     * @param targetMacAddress the mac address of the target
     * @param targetIpAddress the ip address to resolve
     * @param destinationMacAddress the mac address put in Ethernet header
     * @param vlanId the vlan id
     * @return the Ethernet frame containing the ARP request
     */
    public static Ethernet buildArpRequest(byte[] senderMacAddress,
                                           byte[] senderIpAddress,
                                           byte[] targetMacAddress,
                                           byte[] targetIpAddress,
                                           byte[] destinationMacAddress,
                                           short vlanId) {

        if (senderMacAddress.length != MacAddress.MAC_ADDRESS_LENGTH ||
                senderIpAddress.length != Ip4Address.BYTE_LENGTH ||
                targetIpAddress.length != Ip4Address.BYTE_LENGTH) {
            return null;
        }

        ARP arpRequest = new ARP();
        arpRequest.setHardwareType(ARP.HW_TYPE_ETHERNET)
                .setProtocolType(ARP.PROTO_TYPE_IP)
                .setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
                .setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH)
                .setOpCode(ARP.OP_REQUEST)
                .setSenderHardwareAddress(senderMacAddress)
                .setTargetHardwareAddress(targetMacAddress)
                .setSenderProtocolAddress(senderIpAddress)
                .setTargetProtocolAddress(targetIpAddress);

        Ethernet eth = new Ethernet();
        eth.setDestinationMACAddress(destinationMacAddress)
                .setSourceMACAddress(senderMacAddress)
                .setEtherType(Ethernet.TYPE_ARP)
                .setVlanID(vlanId)
                .setPad(true)
                .setPayload(arpRequest);
        return eth;
    }

    /**
     * Builds an ARP request using the supplied parameters.
     *
     * @param senderMacAddress the mac address of the sender
     * @param senderIpAddress the ip address of the sender
     * @param targetIpAddress the ip address to resolve
     * @param vlanId the vlan id
     * @return the Ethernet frame containing the ARP request
     */
    public static Ethernet buildArpRequest(byte[] senderMacAddress,
                                           byte[] senderIpAddress,
                                           byte[] targetIpAddress,
                                           short vlanId) {
        return buildArpRequest(senderMacAddress, senderIpAddress,
                MacAddress.ZERO.toBytes(), targetIpAddress,
                MacAddress.BROADCAST.toBytes(), vlanId);
    }

    /**
     * Builds an ARP reply based on a request.
     *
     * @param srcIp the IP address to use as the reply source
     * @param srcMac the MAC address to use as the reply source
     * @param request the ARP request we got
     * @return an Ethernet frame containing the ARP reply
     */
    public static Ethernet buildArpReply(Ip4Address srcIp, MacAddress srcMac,
            Ethernet request) {

        Ethernet eth = new Ethernet();
        eth.setDestinationMACAddress(request.getSourceMAC());
        eth.setSourceMACAddress(srcMac);
        eth.setEtherType(Ethernet.TYPE_ARP);
        eth.setVlanID(request.getVlanID());

        ARP arp = new ARP();
        arp.setOpCode(ARP.OP_REPLY);
        arp.setProtocolType(ARP.PROTO_TYPE_IP);
        arp.setHardwareType(ARP.HW_TYPE_ETHERNET);

        arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
        arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
        arp.setSenderHardwareAddress(srcMac.toBytes());
        arp.setTargetHardwareAddress(request.getSourceMACAddress());

        arp.setTargetProtocolAddress(((ARP) request.getPayload())
                                             .getSenderProtocolAddress());
        arp.setSenderProtocolAddress(srcIp.toInt());

        eth.setPayload(arp);
        return eth;
    }

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

            ARP arp = new ARP();
            final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
            arp.setHardwareType(bb.getShort());
            arp.setProtocolType(bb.getShort());

            byte hwAddressLength = bb.get();
            arp.setHardwareAddressLength(hwAddressLength);

            byte protocolAddressLength = bb.get();
            arp.setProtocolAddressLength(protocolAddressLength);
            arp.setOpCode(bb.getShort());

            // Check we have enough space for the addresses
            checkHeaderLength(length, INITIAL_HEADER_LENGTH +
                    2 * hwAddressLength +
                    2 * protocolAddressLength);

            arp.senderHardwareAddress = new byte[0xff & hwAddressLength];
            bb.get(arp.senderHardwareAddress, 0, arp.senderHardwareAddress.length);
            arp.senderProtocolAddress = new byte[0xff & protocolAddressLength];
            bb.get(arp.senderProtocolAddress, 0, arp.senderProtocolAddress.length);
            arp.targetHardwareAddress = new byte[0xff & hwAddressLength];
            bb.get(arp.targetHardwareAddress, 0, arp.targetHardwareAddress.length);
            arp.targetProtocolAddress = new byte[0xff & protocolAddressLength];
            bb.get(arp.targetProtocolAddress, 0, arp.targetProtocolAddress.length);

            return arp;
        };
    }

    @Override
    public String toString() {
        return toStringHelper(getClass())
                .add("hardwareType", Short.toString(hardwareType))
                .add("protocolType", Short.toString(protocolType))
                .add("hardwareAddressLength", Byte.toString(hardwareAddressLength))
                .add("protocolAddressLength", Byte.toString(protocolAddressLength))
                .add("opCode", Short.toString(opCode))
                .add("senderHardwareAddress", MacAddress.valueOf(senderHardwareAddress))
                .add("senderProtocolAddress", Ip4Address.valueOf(senderProtocolAddress))
                .add("targetHardwareAddress", MacAddress.valueOf(targetHardwareAddress))
                .add("targetProtocolAddress", Ip4Address.valueOf(targetProtocolAddress))
                .toString();
    }
}
