/*
 * Copyright 2016 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.onosproject.ospf.protocol.ospfpacket.types;

import com.google.common.base.MoreObjects;
import com.google.common.primitives.Bytes;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onlab.packet.Ip4Address;
import org.onosproject.ospf.exceptions.OspfErrorType;
import org.onosproject.ospf.exceptions.OspfParseException;
import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
import org.onosproject.ospf.protocol.util.OspfPacketType;
import org.onosproject.ospf.protocol.util.OspfUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;

/**
 * Defines an OSPF Hello Message, and the fields and methods to access it.
 * Hello packets are OSPF packet type 1. These packets are sent
 * periodically on all interfaces in order to establish and
 * maintain neighbor relationships.
 */
public class HelloPacket extends OspfPacketHeader {

    /*
              0                   1                   2                   3
            0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |   Version #   |       1       |         Packet length         |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |                          Router ID                            |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |                           Area ID                             |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |           Checksum            |             AuType            |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |                       Authentication                          |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |                       Authentication                          |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |                        Network Mask                           |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |         HelloInterval         |    Options    |    Rtr Pri    |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |                     RouterDeadInterval                        |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |                      Designated Router                        |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |                   Backup Designated Router                    |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |                          Neighbor                             |
            +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
            |                              ...                              |

            Hello Message Format
            REFERENCE : RFC 2328
    */

    private static final Logger log = LoggerFactory.getLogger(HelloPacket.class);
    private Ip4Address networkMask;
    private int options;
    private int helloInterval;
    private int routerPriority;
    private int routerDeadInterval;
    private Ip4Address bdr;
    private Ip4Address dr;
    private List<Ip4Address> neighborAddress = new ArrayList<>();

    /**
     * Creates an instance of Hello packet.
     */
    public HelloPacket() {
    }

    /**
     * Creates an instance of Hello packet.
     *
     * @param ospfHeader OSPF header instance.
     */
    public HelloPacket(OspfPacketHeader ospfHeader) {
        populateHeader(ospfHeader);
    }

    /**
     * Gets network mask.
     *
     * @return network mask
     */
    public Ip4Address networkMask() {
        return networkMask;
    }

    /**
     * Sets network mask.
     *
     * @param networkMask network mask
     */
    public void setNetworkMask(Ip4Address networkMask) {
        this.networkMask = networkMask;
    }

    /**
     * Gets BDRs IP address.
     *
     * @return BDRs IP address
     */
    public Ip4Address bdr() {
        return bdr;
    }

    /**
     * Sets BDR IP address.
     *
     * @param bdr BDR IP address
     */
    public void setBdr(Ip4Address bdr) {
        this.bdr = bdr;
    }

    /**
     * Gets DRs IP address.
     *
     * @return DRs IP address
     */
    public Ip4Address dr() {
        return dr;
    }

    /**
     * Sets DRs IP address.
     *
     * @param dr DRs IP address
     */
    public void setDr(Ip4Address dr) {
        this.dr = dr;
    }

    /**
     * Adds neighbor to map.
     *
     * @param neighborID neighbors id
     */
    public void addNeighbor(Ip4Address neighborID) {
        if (!neighborAddress.contains(neighborID)) {
            neighborAddress.add(neighborID);
        }
    }

    /**
     * Checks neighbor is in map or not.
     *
     * @param neighborID neighbors id
     * @return true if neighbor exist else false
     */
    public boolean containsNeighbour(Ip4Address neighborID) {
        return (neighborAddress.contains(neighborID)) ? true : false;
    }

    /**
     * Gets options value.
     *
     * @return options value
     */
    public int options() {
        return options;
    }

    /**
     * Sets options value.
     *
     * @param options options value
     */
    public void setOptions(int options) {
        this.options = options;
    }

    /**
     * Gets router priority.
     *
     * @return routerPriority
     */
    public int routerPriority() {
        return routerPriority;
    }

    /**
     * Sets router priority.
     *
     * @param routerPriority router priority
     */
    public void setRouterPriority(int routerPriority) {
        this.routerPriority = routerPriority;
    }

    /**
     * Gets hello interval.
     *
     * @return hello Interval
     */
    public int helloInterval() {
        return helloInterval;
    }

    /**
     * Sets hello Interval.
     *
     * @param helloInterval hello Interval
     */
    public void setHelloInterval(int helloInterval) {
        this.helloInterval = helloInterval;
    }

    /**
     * Gets router dead interval.
     *
     * @return router dead interval
     */
    public int routerDeadInterval() {
        return routerDeadInterval;
    }

    /**
     * Sets router dead interval.
     *
     * @param routerDeadInterval router dead interval
     */
    public void setRouterDeadInterval(int routerDeadInterval) {
        this.routerDeadInterval = routerDeadInterval;
    }

    @Override
    public OspfPacketType ospfMessageType() {
        return OspfPacketType.HELLO;
    }

    @Override
    public void readFrom(ChannelBuffer channelBuffer) throws OspfParseException {

        try {
            byte[] tempByteArray = new byte[OspfUtil.FOUR_BYTES];
            channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
            this.setNetworkMask(Ip4Address.valueOf(tempByteArray));
            this.setHelloInterval(channelBuffer.readShort());
            this.setOptions(channelBuffer.readByte());
            this.setRouterPriority(channelBuffer.readByte() & 0xff);
            this.setRouterDeadInterval(channelBuffer.readInt());
            tempByteArray = new byte[OspfUtil.FOUR_BYTES];
            channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
            this.setDr(Ip4Address.valueOf(tempByteArray));
            tempByteArray = new byte[OspfUtil.FOUR_BYTES];
            channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
            this.setBdr(Ip4Address.valueOf(tempByteArray));

            while (channelBuffer.readableBytes() > 0) {
                tempByteArray = new byte[OspfUtil.FOUR_BYTES];
                channelBuffer.readBytes(tempByteArray, 0, OspfUtil.FOUR_BYTES);
                this.addNeighbor(Ip4Address.valueOf(tempByteArray));
            }

        } catch (Exception e) {
            log.debug("Error::HelloPacket:: {}", e.getMessage());
            throw new OspfParseException(OspfErrorType.MESSAGE_HEADER_ERROR, OspfErrorType.BAD_MESSAGE_LENGTH);
        }
    }

    @Override
    public byte[] asBytes() {

        byte[] helloMessage = null;
        byte[] helloHeader = getHelloHeaderAsByteArray();
        byte[] helloBody = getHelloBodyAsByteArray();
        helloMessage = Bytes.concat(helloHeader, helloBody);

        log.debug("HelloPacket::asBytes::Hello asBytes:: {}", helloMessage);

        return helloMessage;
    }

    /**
     * Gets hello header as byte array.
     *
     * @return hello header
     */
    public byte[] getHelloHeaderAsByteArray() {
        List<Byte> headerLst = new ArrayList<>();
        try {
            headerLst.add((byte) this.ospfVersion());
            headerLst.add((byte) this.ospfType());
            headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.ospfPacLength())));
            headerLst.addAll(Bytes.asList(this.routerId().toOctets()));
            headerLst.addAll(Bytes.asList(this.areaId().toOctets()));
            headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.checksum())));
            headerLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.authType())));
            //Authentication is 0 always. Total 8 bytes consist of zero
            byte[] auth = new byte[OspfUtil.EIGHT_BYTES];
            headerLst.addAll(Bytes.asList(auth));
        } catch (Exception e) {
            log.debug("Error::getHelloHeaderAsByteArray {}", e.getMessage());
            return Bytes.toArray(headerLst);
        }

        return Bytes.toArray(headerLst);
    }

    /**
     * Gets hello body as byte array.
     *
     * @return hello body as byte array
     */
    public byte[] getHelloBodyAsByteArray() {
        List<Byte> bodyLst = new ArrayList<>();

        try {
            bodyLst.addAll(Bytes.asList(this.networkMask().toOctets()));
            bodyLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.helloInterval())));
            bodyLst.add((byte) this.options());
            bodyLst.add((byte) this.routerPriority());
            bodyLst.addAll(Bytes.asList(OspfUtil.convertToFourBytes(this.routerDeadInterval())));
            bodyLst.addAll(Bytes.asList(this.dr().toOctets()));
            bodyLst.addAll(Bytes.asList(this.bdr().toOctets()));
            for (Ip4Address neighbour : neighborAddress) {
                bodyLst.addAll(Bytes.asList(neighbour.toOctets()));
            }

        } catch (Exception e) {
            log.debug("Error::getHelloBodyAsByteArray {}", e.getMessage());
            return Bytes.toArray(bodyLst);
        }

        return Bytes.toArray(bodyLst);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .omitNullValues()
                .add("networkMask", networkMask)
                .add("options", options)
                .add("helloInterval", helloInterval)
                .add("routerPriority", routerPriority)
                .add("routerDeadInterval", routerDeadInterval)
                .add("bdr", bdr)
                .add("dr", dr)
                .toString();
    }
}