/*
 *
 *  * Copyright 2015 AT&T Foundry
 *  *
 *  * 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.onosproject.aaa.packet;

import org.onlab.packet.BasePacket;
import org.onlab.packet.Ethernet;
import org.onlab.packet.IPacket;
import org.onlab.packet.MacAddress;

import java.nio.ByteBuffer;

/**
 *
 */
public class EAPOL extends BasePacket {

    private byte version = 0x01;
    private byte eapolType;
    private short packetLength;

    /* EAPOL Packet Type */
    public static final byte EAPOL_PACKET = 0x0;
    public static final byte EAPOL_START  = 0x1;
    public static final byte EAPOL_LOGOFF = 0x2;
    public static final byte EAPOL_KEY    = 0x3;
    public static final byte EAPOL_ASF    = 0x4;

    public static final MacAddress PAE_GROUP_ADDR = MacAddress.valueOf(new byte[] {
            (byte) 0x01, (byte) 0x80, (byte) 0xc2, (byte) 0x00, (byte) 0x00, (byte) 0x03
    });


    /**
     * Get version.
     * @return version
     */
    public byte getVersion() {
        return this.version;
    }

    /**
     * Set version.
     * @param version EAPOL version
     * @return this
     */
    public EAPOL setVersion(final byte version) {
        this.version = version;
        return this;
    }

    /**
     * Get type.
     * @return EAPOL type
     */
    public byte getEapolType() {
        return this.eapolType;
    }

    /**
     * Set EAPOL type.
     * @param eapolType EAPOL type
     * @return this
     */
    public EAPOL setEapolType(final byte eapolType) {
        this.eapolType = eapolType;
        return this;
    }

    /**
     * Get packet length.
     * @return packet length
     */
    public short getPacketLength() {
        return this.packetLength;
    }

    /**
     * Set packet length.
     * @param packetLen packet length
     * @return this
     */
    public EAPOL setPacketLength(final short packetLen) {
        this.packetLength = packetLen;
        return this;
    }



    /**
     * Serializes the packet, based on the code/type using the payload
     * to compute its length.
     * @return this
     */
    @Override
    public byte[] serialize() {

        byte[] payloadData = null;

        if (this.payload != null) {
            this.payload.setParent(this);
            payloadData = this.payload.serialize();
        }

        //prepare the buffer to hold the version (1), packet type (1), packet length (2) and the eap payload.
        //if there is no payload, packet length is 0
        byte[] data = new byte[4 + this.packetLength];
        final ByteBuffer bb = ByteBuffer.wrap(data);
        bb.put(this.version);
        bb.put(this.eapolType);
        bb.putShort(this.packetLength);

        //put the EAP payload
        if (payloadData != null) {
            bb.put(payloadData);
        }

        return data;
    }

    @Override
    public IPacket deserialize(final byte[] data, final int offset,
                               final int length) {
        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);


        //deserialize the EAPOL header
        this.version = bb.get();
        this.eapolType = bb.get();
        this.packetLength = bb.getShort();

        if (this.packetLength > 0) {
            //deserialize the EAP Payload
            this.payload = new EAP();

            this.payload = this.payload.deserialize(data, bb.position(), length - 4);
            this.payload.setParent(this);
        }


        return this;
    }

    @Override
    public int hashCode() {
        final int prime = 3889;
        int result = super.hashCode();
        result = prime * result + this.version;
        result = prime * result + this.eapolType;
        result = prime * result + this.packetLength;
        return result;
    }

    /**
     *
     * @param dstMac
     * @param srcMac
     * @param eapolType
     * @param eap
     * @return Ethernet frame
     */
    public static Ethernet buildEapolResponse(MacAddress dstMac, MacAddress srcMac,
                                              short vlan, byte eapolType, EAP eap) {

        Ethernet eth = new Ethernet();
        eth.setDestinationMACAddress(dstMac.toBytes());
        eth.setSourceMACAddress(srcMac.toBytes());
        eth.setEtherType(EAPEthernet.TYPE_PAE);
        if (vlan != Ethernet.VLAN_UNTAGGED) {
            eth.setVlanID(vlan);
        }
        //eapol header
        EAPOL eapol = new EAPOL();
        eapol.setEapolType(eapolType);
        eapol.setPacketLength(eap.getLength());

        //eap part
        eapol.setPayload(eap);

        eth.setPayload(eapol);
        eth.setPad(true);
        return eth;
    }
}

