/*
 * Copyright 2016-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.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.controller.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();
    }
}