/*
 * 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.onosproject.ospf.exceptions.OspfErrorType;
import org.onosproject.ospf.exceptions.OspfParseException;
import org.onosproject.ospf.protocol.lsa.LsaHeader;
import org.onosproject.ospf.protocol.lsa.OpaqueLsaHeader;
import org.onosproject.ospf.protocol.ospfpacket.OspfPacketHeader;
import org.onosproject.ospf.controller.OspfPacketType;
import org.onosproject.ospf.protocol.util.OspfParameters;
import org.onosproject.ospf.protocol.util.OspfUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

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

/**
 * Representation of an OSPF Database Description packet.
 * Database Description packets are OSPF packet type 2.
 * These packets are exchanged when an adjacency is being initialized.
 * They describe the contents of the link-state database.
 */
public class DdPacket 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 #   |       2       |         Packet length         |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                          Router ID                            |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                           Area ID                             |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |           Checksum            |             AuType            |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                       Authentication                          |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                       Authentication                          |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |         Interface MTU         |    Options    |0|0|0|0|0|I|M|MS
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                     DD sequence number                        |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                                                               |
       +-                                                             -+
       |                                                               |
       +-                      An LSA Header                          -+
       |                                                               |
       +-                                                             -+
       |                                                               |
       +-                                                             -+
       |                                                               |
       +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
       |                              ...                              |
     */
    private static final Logger log = LoggerFactory.getLogger(DdPacket.class);
    private int imtu;
    private int options;
    private int ims; // initialize , more but / master slave bit
    private int isMaster;
    private int isInitialize;
    private int isMore;
    private long sequenceNo;
    private boolean isOpaqueCapable;
    private List<LsaHeader> lsaHeaderList = new ArrayList<>();

    /**
     * Creates an instance of DD packet.
     */
    public DdPacket() {
    }

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

    /**
     * Gets is opaque capable or not.
     *
     * @return true if opaque capable else false
     */
    public boolean isOpaqueCapable() {
        return isOpaqueCapable;
    }

    /**
     * Sets is opaque capable or not.
     *
     * @param isOpaqueCapable true or false
     */
    public void setIsOpaqueCapable(boolean isOpaqueCapable) {
        this.isOpaqueCapable = isOpaqueCapable;
    }

    /**
     * Gets IMS value.
     *
     * @return IMS bits as an int value
     */
    public int ims() {
        return ims;
    }

    /**
     * Sets IMS value.
     *
     * @param ims IMS value
     */
    public void setIms(int ims) {
        this.ims = ims;
    }

    /**
     * Gets master bit value.
     *
     * @return 1 if master else 0
     */
    public int isMaster() {
        return isMaster;
    }

    /**
     * Sets master value.
     *
     * @param isMaster 1 represents master
     */
    public void setIsMaster(int isMaster) {
        this.isMaster = isMaster;
    }

    /**
     * Gets Initialize bit value.
     *
     * @return 1 if initialize else 0
     */
    public int isInitialize() {
        return isInitialize;
    }

    /**
     * Sets initialize value.
     *
     * @param isInitialize 1 is initialize else 0
     */
    public void setIsInitialize(int isInitialize) {
        this.isInitialize = isInitialize;
    }

    /**
     * Gets is more bit set or not.
     *
     * @return 1 if more set else 0
     */
    public int isMore() {
        return isMore;
    }

    /**
     * Sets more bit value to 0 or 1.
     *
     * @param isMore 1 if more set else 0
     */
    public void setIsMore(int isMore) {
        this.isMore = isMore;
    }


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

    /**
     * Sets IMTU value.
     *
     * @param imtu value
     */
    public void setImtu(int imtu) {
        this.imtu = imtu;
    }

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

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

    /**
     * Gets sequence number.
     *
     * @return sequenceNo
     */
    public long sequenceNo() {
        return sequenceNo;
    }

    /**
     * Sets Sequence number.
     *
     * @param sequenceNo sequence number
     */
    public void setSequenceNo(long sequenceNo) {
        this.sequenceNo = sequenceNo;
    }

    /**
     * Gets LSA header list.
     *
     * @return LSA header
     */
    public List<LsaHeader> getLsaHeaderList() {
        return lsaHeaderList;
    }

    /**
     * Adds LSA header to header list.
     *
     * @param lsaHeader lsa header instance
     */
    public void addLsaHeader(LsaHeader lsaHeader) {

        if (!lsaHeaderList.contains(lsaHeader)) {
            lsaHeaderList.add(lsaHeader);
        }
    }

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

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

        try {
            this.setImtu(channelBuffer.readShort());

            int options = channelBuffer.readByte();
            String obit = Integer.toHexString(options);
            if (obit.length() == 1) {
                obit = "0" + obit;
            }
            String toBinary = Integer.toBinaryString(Integer.parseInt(new Character(obit.charAt(0)).toString()));
            if (toBinary.length() == 1) {
                toBinary = "000" + toBinary;
            } else if (toBinary.length() == 2) {
                toBinary = "00" + toBinary;
            } else if (toBinary.length() == 3) {
                toBinary = "0" + toBinary;
            }
            if (Integer.parseInt(new Character(toBinary.charAt(1)).toString()) == 1) {
                this.setIsOpaqueCapable(true);
            }
            this.setOptions(options);
            this.setIms(channelBuffer.readByte());
            //Convert the byte to ims bits
            String strIms = Integer.toBinaryString(this.ims());
            if (strIms.length() == 3) {
                this.setIsInitialize(Integer.parseInt(Character.toString(strIms.charAt(0))));
                this.setIsMore(Integer.parseInt(Character.toString(strIms.charAt(1))));
                this.setIsMaster(Integer.parseInt(Character.toString(strIms.charAt(2))));
            } else if (strIms.length() == 2) {
                this.setIsInitialize(0);
                this.setIsMore(Integer.parseInt(Character.toString(strIms.charAt(0))));
                this.setIsMaster(Integer.parseInt(Character.toString(strIms.charAt(1))));
            } else if (strIms.length() == 1) {
                this.setIsInitialize(0);
                this.setIsMore(0);
                this.setIsMaster(Integer.parseInt(Character.toString(strIms.charAt(0))));
            }
            this.setSequenceNo(channelBuffer.readInt());

            //add all the LSA Headers - header is of 20 bytes
            while (channelBuffer.readableBytes() >= OspfUtil.LSA_HEADER_LENGTH) {
                LsaHeader header = OspfUtil.readLsaHeader(channelBuffer.readBytes(OspfUtil.LSA_HEADER_LENGTH));
                //add the LSAHeader to DDPacket
                addLsaHeader(header);
            }

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

    @Override
    public byte[] asBytes() {

        byte[] ddMessage = null;

        byte[] ddHeader = getDdHeaderAsByteArray();
        byte[] ddBody = getDdBodyAsByteArray();
        ddMessage = Bytes.concat(ddHeader, ddBody);

        return ddMessage;
    }

    /**
     * Gets DD Header as byte array.
     *
     * @return dd header as byte array.
     */
    public byte[] getDdHeaderAsByteArray() {
        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");

        }

        return Bytes.toArray(headerLst);
    }


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

        try {
            bodyLst.addAll(Bytes.asList(OspfUtil.convertToTwoBytes(this.imtu())));
            bodyLst.add((byte) this.options());

            StringBuilder sb = new StringBuilder();
            sb.append(this.isInitialize());
            sb.append(this.isMore());
            sb.append(this.isMaster());

            bodyLst.add((byte) Integer.parseInt(sb.toString(), 2));
            bodyLst.addAll(Bytes.asList(OspfUtil.convertToFourBytes(this.sequenceNo()))); // passing long value

            for (LsaHeader lsaHeader : lsaHeaderList) {
                if (lsaHeader.lsType() == OspfParameters.LINK_LOCAL_OPAQUE_LSA ||
                        lsaHeader.lsType() == OspfParameters.AREA_LOCAL_OPAQUE_LSA ||
                        lsaHeader.lsType() == OspfParameters.AS_OPAQUE_LSA) {
                    OpaqueLsaHeader header = (OpaqueLsaHeader) lsaHeader;
                    bodyLst.addAll(Bytes.asList(header.getOpaqueLsaHeaderAsByteArray()));
                } else {
                    bodyLst.addAll(Bytes.asList(lsaHeader.getLsaHeaderAsByteArray()));
                }
            }
        } catch (Exception e) {
            log.debug("Error::getLsrBodyAsByteArray {}", e.getMessage());
            return Bytes.toArray(bodyLst);
        }

        return Bytes.toArray(bodyLst);
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .omitNullValues()
                .add("imtu", imtu)
                .add("options", options)
                .add("ims", ims)
                .add("isMaster", isMaster)
                .add("isInitialize", isInitialize)
                .add("isMore", isMore)
                .add("sequenceNo", sequenceNo)
                .add("isOpaqueCapable", isOpaqueCapable)
                .add("lsaHeaderList", lsaHeaderList)
                .toString();
    }
}