/*
 * Copyright 2014-2015 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.ipv6;

import org.onlab.packet.BasePacket;
import org.onlab.packet.Data;
import org.onlab.packet.IPacket;
import org.onlab.packet.IPv6;
import java.nio.ByteBuffer;

/**
 * Implements IPv6 Encapsulating Security Payload (ESP) extension header format.
 * (RFC 4303)
 */
public class EncapSecurityPayload extends BasePacket {
    public static final byte HEADER_LENGTH = 8; // bytes

    protected int securityParamIndex;
    protected int sequence;
    //
    // NOTE: The remaining fields including payload data, padding length and
    //       next header are encrypted and all considered as a payload of ESP.
    //

    /**
     * Gets the security parameter index of this header.
     *
     * @return the security parameter index
     */
    public int getSecurityParamIndex() {
        return this.securityParamIndex;
    }

    /**
     * Sets the security parameter index of this header.
     *
     * @param securityParamIndex the security parameter index to set
     * @return this
     */
    public EncapSecurityPayload setSecurityParamIndex(final int securityParamIndex) {
        this.securityParamIndex = securityParamIndex;
        return this;
    }

    /**
     * Gets the sequence number of this header.
     *
     * @return the sequence number
     */
    public int getSequence() {
        return this.sequence;
    }

    /**
     * Sets the sequence number of this header.
     *
     * @param sequence the sequence number to set
     * @return this
     */
    public EncapSecurityPayload setSequence(final int sequence) {
        this.sequence = sequence;
        return this;
    }

    @Override
    public byte[] serialize() {
        byte[] payloadData = null;
        if (this.payload != null) {
            this.payload.setParent(this);
            payloadData = this.payload.serialize();
        }

        int payloadLength = 0;
        if (payloadData != null) {
            payloadLength = payloadData.length;
        }

        final byte[] data = new byte[HEADER_LENGTH + payloadLength];
        final ByteBuffer bb = ByteBuffer.wrap(data);

        bb.putInt(this.securityParamIndex);
        bb.putInt(this.sequence);

        if (payloadData != null) {
            bb.put(payloadData);
        }

        if (this.parent != null && this.parent instanceof IExtensionHeader) {
            ((IExtensionHeader) this.parent).setNextHeader(IPv6.PROTOCOL_ESP);
        }
        return data;
    }

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

        this.payload = new Data();
        this.payload.deserialize(data, bb.position(),
                bb.limit() - bb.position());
        this.payload.setParent(this);

        return this;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 5807;
        int result = super.hashCode();
        result = prime * result + this.securityParamIndex;
        result = prime * result + this.sequence;
        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 EncapSecurityPayload)) {
            return false;
        }
        final EncapSecurityPayload other = (EncapSecurityPayload) obj;
        if (this.securityParamIndex != other.securityParamIndex) {
            return false;
        }
        if (this.sequence != other.sequence) {
            return false;
        }
        return true;
    }
}
