/*
 * Copyright 2019-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.opencord.bng.packets;

import com.google.common.base.Objects;
import com.google.common.collect.Lists;
import org.onlab.packet.DeserializationException;
import org.onlab.packet.Deserializer;
import org.onlab.packet.IpAddress;

import java.nio.ByteBuffer;
import java.util.List;

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

/**
 * Implements the IP Control Protocol (IPCP) packet format.
 */

public class Ipcp extends Ppp {

    public static final byte CONF_REQ = 0x01;
    public static final byte ACK = 0x02;
    public static final byte NAK = 0x03;

    private PppTlv ipaddresstlv = null;

    private List<PppTlv> pppTlvList;

    Ipcp() {
        super();
        pppTlvList = Lists.newLinkedList();
    }

    /**
     * Gets the IP Address TLV field.
     *
     * @return the IP Address TLV field if present, null otherwise
     */
    public PppTlv getIpAddressTlv() {
        return this.ipaddresstlv;
    }

    /**
     * Gets the IP address TLV field as an IpAddress object.
     *
     * @return The IP address TLV field as IpAddress object, it will be address
     * 0 if no TLV address is present in the packet
     */
    public IpAddress getIpAddress() {
        return IpAddress.valueOf(IpAddress.Version.INET,
                                 this.getIpAddressTlv().getValue());
    }

    /**
     * Sets the IP address TLV field.
     *
     * @param ipaddresstlv the IP address TLV to set
     * @return this
     */
    public Ipcp setIpAddressTlv(PppTlv ipaddresstlv) {
        this.ipaddresstlv = ipaddresstlv;
        return this;
    }

    /**
     * Gets the TLV field list.
     *
     * @return the IPCP TLV field list
     */
    public List<PppTlv> getIpcpTlvList() {
        return this.pppTlvList;
    }

    @Override
    public byte[] serialize() {
        // TODO: Can it have any payload?
        final byte[] data = new byte[this.length];
        final ByteBuffer bb = ByteBuffer.wrap(data);
        bb.put(this.code);
        bb.put(this.identifier);
        bb.putShort(this.length);
        if (ipaddresstlv != null) {
            bb.put(ipaddresstlv.serialize());
        }
        if (this.pppTlvList != null) {
            for (final PppTlv tlv : this.pppTlvList) {
                bb.put(tlv.serialize());
            }
        }
        return data;
    }

    /**
     * Deserializer function for IPCP packets.
     *
     * @return deserializer function
     */
    public static Deserializer<Ipcp> deserializer() {
        return (data, offset, length) -> {
            checkInput(data, offset, length, MIN_HEADER_LENGTH);
            Ipcp ipcp = new Ipcp();
            ByteBuffer bb = ByteBuffer.wrap(data, offset, length);
            ipcp.code = bb.get();
            ipcp.identifier = bb.get();
            ipcp.length = bb.getShort();
            short currentIndex = MIN_HEADER_LENGTH;
            PppTlv tlv;
            while (currentIndex < ipcp.length) {
                // Each new TLV IPCP must be a minimum of 2 bytes
                // (containing the type and length fields).
                currentIndex += 2;
                checkHeaderLength(length, currentIndex);

                tlv = (new PppTlv()).deserialize(bb);
                // if there was a failure to deserialize stop processing TLVs
                if (tlv == null) {
                    break;
                }
                if (tlv.getType() == PppTlv.IPCPTLV_IP_ADDRESS) {
                    ipcp.ipaddresstlv = tlv;
                } else {
                    ipcp.pppTlvList.add(tlv);
                }
                currentIndex += tlv.getLength() - 2;
            }
            if (currentIndex != ipcp.length) {
                throw new DeserializationException("Length of packet do not correspond to IPCP TLVs options");
            }
            return ipcp;
        };
    }

    @Override
    public int hashCode() {
        return 31 * super.hashCode() + Objects.hashCode(ipaddresstlv);
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        if (!super.equals(obj)) {
            return false;
        }
        final Ipcp other = (Ipcp) obj;
        return Objects.equal(this.ipaddresstlv, other.ipaddresstlv);
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("code", code)
                .add("identifier", identifier)
                .add("length", length)
                .add("pppTlvList", pppTlvList)
                .add("ipaddresstlv", ipaddresstlv)
                .toString();
    }
}
