/*
 * Copyright 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.pim;

import org.onlab.packet.DeserializationException;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.Ip6Address;

import java.nio.ByteBuffer;

import static org.onlab.packet.PacketUtils.checkInput;

public class PIMAddrSource {
    private byte family;
    private byte encType;
    private byte reserved;
    private boolean sBit;
    private boolean wBit;
    private boolean rBit;
    private byte masklen;
    IpAddress addr;

    public static final int ENC_SOURCE_IPV4_BYTE_LENGTH = 4 + Ip4Address.BYTE_LENGTH;
    public static final int ENC_SOURCE_IPV6_BYTE_LENGTH = 4 + Ip6Address.BYTE_LENGTH;

    /**
     * PIM Encoded Source Address.
     *
     * @param addr IPv4 or IPv6
     */
    public PIMAddrSource(String addr) {
        this.init();
        this.setAddr(addr);
    }

    /**
     * PIM Encoded Source Address.
     *
     * @param spfx IPv4 or IPv6
     */
    public PIMAddrSource(IpPrefix spfx) {
        this.init();
        this.setAddr(spfx);
    }

    /**
     * PIM Encoded Group Address.
     */
    public PIMAddrSource() {
        this.init();
    }

    private void init() {
        this.family = 4;
        this.encType = 0;
        this.reserved = 0;
        this.sBit = true;
        this.wBit = false;
        this.rBit = false;
    }

    /**
     * PIM Encoded Source Address.
     *
     * @param addr IPv4 or IPv6
     */
    public void setAddr(String addr) {
        IpPrefix spfx = IpPrefix.valueOf(addr);
        setAddr(spfx);
    }

    /**
     * PIM Encoded Source Address.
     *
     * @param spfx IPv4 or IPv6 address prefix
     */
    public void setAddr(IpPrefix spfx) {
        this.addr = spfx.address();
        this.masklen = (byte) spfx.prefixLength();
        this.family = (byte) ((this.addr.isIp4()) ? 4 : 6);
    }

    /**
     * Get the IP family of this address: 4 or 6.
     *
     * @return the IP address family
     */
    public byte getFamily() {
        return this.family;
    }

    /**
     * Get the address of this encoded address.
     *
     * @return source address
     */
    public IpAddress getAddr() {
        return this.addr;
    }

    /**
     * Get the masklen of the group address.
     *
     * @return the masklen
     */
    public int getMasklen() {
        return this.masklen;
    }

    /**
     * Return the sparse bit.
     *
     * @return true or false
     */
    public boolean getSBit() {
        return this.sBit;
    }

    /**
     * Return the wBit, used in Join/Prune messages.
     *
     * @return return true or false.
     */
    public boolean getWBit() {
        return this.wBit;
    }

    /**
     * Return the rBit. Used by Rendezvous Point.
     *
     * @return the rBit.
     */
    public boolean getRBit() {
        return this.rBit;
    }

    /**
     * The size in bytes of a serialized address.
     *
     * @return the number of bytes when serialized
     */
    public int getByteSize() {
        int size = 4;
        size += addr.isIp4() ? 4 : 16;
        return size;
    }

    public byte[] serialize() {
        int len = addr.isIp4() ? ENC_SOURCE_IPV4_BYTE_LENGTH : ENC_SOURCE_IPV6_BYTE_LENGTH;

        final byte[] data = new byte[len];
        final ByteBuffer bb = ByteBuffer.wrap(data);

        bb.put(this.family);
        bb.put(this.encType);

        // Todo: technically we should be setting the B and Z bits, but we'll never use them.
        byte mask = 0x0;
        if (this.sBit) {
            this.reserved |= 0x4;
        }
        if (this.wBit) {
            this.reserved |= 0x2;
        }
        if (this.rBit) {
            this.reserved |= 0x1;
        }
        bb.put(reserved);

        bb.put(this.masklen);
        bb.put(this.addr.toOctets());
        return data;
    }

    public PIMAddrSource deserialize(byte[] data, int offset, int length) throws DeserializationException {
        final ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
        return deserialize(bb);
    }

    public PIMAddrSource deserialize(ByteBuffer bb) throws DeserializationException {

        /*
         * We need to verify that we have enough buffer space.  First we'll assume that
         * we are decoding an IPv4 address.  After we read the first by (address family),
         * we'll determine if we actually need more buffer space for an IPv6 address.
         */
        checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_SOURCE_IPV4_BYTE_LENGTH);

        this.family = bb.get();
        if (family != 4 && family != 6) {
            throw new DeserializationException("Illegal IP version number: " + family + "\n");
        } else if (family == 6) {

            // Check for one less by since we have already read the first byte of the packet.
            checkInput(bb.array(), bb.position(), bb.limit() - bb.position(), ENC_SOURCE_IPV6_BYTE_LENGTH - 1);
        }

        this.encType = bb.get();
        this.reserved = bb.get();
        if ((this.reserved & 0x01) != 0) {
            this.rBit = true;
        }
        if ((this.reserved & 0x02) != 0) {
            this.wBit = true;
        }
        if ((this.reserved & 0x4) != 0) {
            this.sBit = true;
        }

        // Remove the s, reserved
        this.reserved &= 0xf8;

        this.masklen = bb.get();
        if (this.family == 4) {
            this.addr = IpAddress.valueOf(bb.getInt());
        } else if (this.family == 6) {
            this.addr = Ip6Address.valueOf(bb.array(), 2);
        }
        return this;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {
        final int prime = 2521;
        int result = super.hashCode();
        result = prime * result + this.family;
        result = prime * result + this.encType;
        result = prime * result + this.reserved;
        result = prime * result + this.masklen;
        result = prime * result + this.addr.hashCode();
        return result;
    }

    /*
     * (non-Javadoc)
     *
     * @see java.lang.Object#hashCode()
     */
    @Override
    public boolean equals(final Object obj) {
        if (this == obj) {
            return true;
        }
        if (!(obj instanceof PIMAddrSource)) {
            return false;
        }
        final PIMAddrSource other = (PIMAddrSource) obj;
        if (this.family != this.family) {
            return false;
        }

        if (this.encType != other.encType) {
            return false;
        }

        if (!this.addr.equals(other.addr)) {
            return false;
        }
        return true;
    }
}
