/*
 * Copyright 2015-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.bgpio.types;

import com.google.common.base.MoreObjects;
import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.protocol.BgpEvpnNlri;
import org.onosproject.bgpio.protocol.BgpLSNlri;
import org.onosproject.bgpio.protocol.evpn.BgpEvpnNlriImpl;
import org.onosproject.bgpio.protocol.evpn.BgpEvpnRouteType2Nlri;
import org.onosproject.bgpio.protocol.flowspec.BgpFlowSpecNlri;
import org.onosproject.bgpio.protocol.linkstate.BgpLinkLsNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.BgpNodeLSNlriVer4;
import org.onosproject.bgpio.protocol.linkstate.BgpPrefixIPv4LSNlriVer4;
import org.onosproject.bgpio.util.Constants;
import org.onosproject.bgpio.util.Validation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;

/**
 * Provides Implementation of MpUnReach Nlri BGP Path Attribute.
 */
public class MpUnReachNlri implements BgpValueType {

    private static final Logger log = LoggerFactory.getLogger(MpUnReachNlri.class);
    public static final byte MPUNREACHNLRI_TYPE = 15;
    public static final byte LINK_NLRITYPE = 2;
    public static final byte FLAGS = (byte) 0x90;
    private boolean isMpUnReachNlri = false;
    private final short afi;
    private final byte safi;
    private final List<BgpLSNlri> mpUnReachNlri;
    private final int length;
    private BgpFlowSpecNlri bgpFlowSpecNlri;
    private List<BgpEvpnNlri> evpnNlri;

    /**
     * Constructor to initialize parameters.
     *
     * @param mpUnReachNlri MpUnReach  Nlri attribute
     * @param afi address family identifier
     * @param safi subsequent address family identifier
     * @param length of MpUnReachNlri
     */
    public MpUnReachNlri(List<BgpLSNlri> mpUnReachNlri, short afi, byte safi,
                  int length) {
        this.mpUnReachNlri = mpUnReachNlri;
        this.isMpUnReachNlri = true;
        this.afi = afi;
        this.safi = safi;
        this.length = length;
    }

    /**
     * Constructor to initialize parameters.
     *
     * @param bgpFlowSpecNlri bgpFlowSpecNlri
     * @param afi             afi
     * @param safi            safi
     */
    public MpUnReachNlri(BgpFlowSpecNlri bgpFlowSpecNlri, short afi, byte safi) {
        this.mpUnReachNlri = null;
        this.isMpUnReachNlri = true;
        this.length = 0;
        this.bgpFlowSpecNlri = bgpFlowSpecNlri;
        this.afi = afi;
        this.safi = safi;
    }

    /**
     * Constructor to initialize parameters.
     *
     * @param evpnNlri evpnNlri
     * @param afi      afi
     * @param safi     safi
     */
    public MpUnReachNlri(List<BgpEvpnNlri> evpnNlri, short afi, byte safi) {
        this.mpUnReachNlri = null;
        this.isMpUnReachNlri = true;
        this.length = 0;
        this.evpnNlri = evpnNlri;
        this.afi = afi;
        this.safi = safi;
    }

    /**
     * Returns BGP flow specification info.
     *
     * @return BGP flow specification info
     */
    public BgpFlowSpecNlri bgpFlowSpecNlri() {
        return this.bgpFlowSpecNlri;
    }

    /**
     * Returns BGP Evpn info.
     *
     * @return BGP Evpn info
     */
    public List<BgpEvpnNlri> bgpEvpnNlri() {
        return this.evpnNlri;
    }

    /**
     * Returns afi.
     *
     * @return afi
     */
    public short getAfi() {
        return this.afi;
    }

    /**
     * Returns safi.
     *
     * @return safi
     */
    public byte getSafi() {
        return this.safi();
    }

    /**
     * Returns mpUnReachNlri details type.
     *
     * @return type
     */
    public BgpNlriType getNlriDetailsType() {
        if ((this.afi == Constants.AFI_VALUE)
                && (this.safi == Constants.SAFI_VALUE)
                || (this.afi == Constants.AFI_VALUE)
                && (this.safi == Constants.VPN_SAFI_VALUE)) {
            return BgpNlriType.LINK_STATE;
        }

        if ((afi == Constants.AFI_FLOWSPEC_VALUE)
                && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
                || (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
            return BgpNlriType.FLOW_SPEC;
        }

        if ((afi == Constants.AFI_EVPN_VALUE)
                && (safi == Constants.SAFI_EVPN_VALUE)) {
            return BgpNlriType.EVPN;
        }

        return null;
    }

    /**
     * Reads from ChannelBuffer and parses MpUnReachNlri.
     *
     * @param cb ChannelBuffer
     * @return object of MpUnReachNlri
     * @throws BgpParseException while parsing MpUnReachNlri
     */
    public static MpUnReachNlri read(ChannelBuffer cb) throws BgpParseException {
        ChannelBuffer tempBuf = cb.copy();
        Validation parseFlags = Validation.parseAttributeHeader(cb);
        int len = parseFlags.isShort() ? parseFlags.getLength() + Constants.TYPE_AND_LEN_AS_SHORT
                                      : parseFlags.getLength() + Constants.TYPE_AND_LEN_AS_BYTE;
        ChannelBuffer data = tempBuf.readBytes(len);

        if (!parseFlags.getFirstBit() && parseFlags.getSecondBit()
                && parseFlags.getThirdBit()) {
            throw new BgpParseException(BgpErrorType.UPDATE_MESSAGE_ERROR,
                                        BgpErrorType.ATTRIBUTE_FLAGS_ERROR, data);
        }

        if (cb.readableBytes() < parseFlags.getLength()) {
            Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
                                   BgpErrorType.ATTRIBUTE_LENGTH_ERROR, parseFlags.getLength());
        }

        LinkedList<BgpLSNlri> mpUnReachNlri = new LinkedList<>();
        BgpLSNlri bgpLSNlri = null;
        short afi = 0;
        byte safi = 0;
        ChannelBuffer tempCb = cb.readBytes(parseFlags.getLength());
        while (tempCb.readableBytes() > 0) {
            afi = tempCb.readShort();
            safi = tempCb.readByte();

            //Supporting only for AFI 16388 / SAFI 71
            if ((afi == Constants.AFI_VALUE) && (safi == Constants.SAFI_VALUE)
                    || (afi == Constants.AFI_VALUE) && (safi == Constants.VPN_SAFI_VALUE)) {
                while (tempCb.readableBytes() > 0) {
                    short nlriType = tempCb.readShort();
                    short totNlriLen = tempCb.readShort();
                    if (tempCb.readableBytes() < totNlriLen) {
                        Validation.validateLen(
                                BgpErrorType.UPDATE_MESSAGE_ERROR,
                                BgpErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen);
                    }
                    tempBuf = tempCb.readBytes(totNlriLen);
                    switch (nlriType) {
                    case BgpNodeLSNlriVer4.NODE_NLRITYPE:
                        bgpLSNlri = BgpNodeLSNlriVer4.read(tempBuf, afi, safi);
                        break;
                    case BgpLinkLsNlriVer4.LINK_NLRITYPE:
                        bgpLSNlri = BgpLinkLsNlriVer4.read(tempBuf, afi, safi);
                        break;
                    case BgpPrefixIPv4LSNlriVer4.PREFIX_IPV4_NLRITYPE:
                        bgpLSNlri = BgpPrefixIPv4LSNlriVer4.read(tempBuf, afi,
                                                                 safi);
                        break;
                    default:
                        log.debug("nlriType not supported" + nlriType);
                        break;
                    }
                    mpUnReachNlri.add(bgpLSNlri);
                }
            } else if ((afi == Constants.AFI_FLOWSPEC_VALUE)
                                               && ((safi == Constants.SAFI_FLOWSPEC_VALUE)
                                               || (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
                List<BgpValueType> flowSpecComponents = new LinkedList<>();
                RouteDistinguisher routeDistinguisher = null;
                if (tempCb.readableBytes() > 0) {
                    BgpValueType flowSpecComponent = null;

                    if (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE) {
                        routeDistinguisher = new RouteDistinguisher();
                        routeDistinguisher = RouteDistinguisher.read(tempCb);
                    }
                    while (tempCb.readableBytes() > 0) {
                        short totNlriLen = tempCb.getUnsignedByte(tempCb.readerIndex());
                        if (totNlriLen >= BgpFlowSpecNlri.FLOW_SPEC_LEN) {
                           if (tempCb.readableBytes() < 2) {
                                Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
                                    BgpErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen);
                            }
                            totNlriLen = tempCb.readShort();
                        } else {
                            totNlriLen = tempCb.readByte();
                        }
                        if (tempCb.readableBytes() < totNlriLen) {
                            Validation.validateLen(BgpErrorType.UPDATE_MESSAGE_ERROR,
                                    BgpErrorType.ATTRIBUTE_LENGTH_ERROR, totNlriLen);
                        }
                        tempBuf = tempCb.readBytes(totNlriLen);
                        while (tempBuf.readableBytes() > 0) {
                            short type = tempBuf.readByte();
                            switch (type) {
                            case Constants.BGP_FLOWSPEC_DST_PREFIX:
                                flowSpecComponent = BgpFsDestinationPrefix.read(tempBuf);
                                break;
                            case Constants.BGP_FLOWSPEC_SRC_PREFIX:
                                flowSpecComponent = BgpFsSourcePrefix.read(tempBuf);
                                break;
                            case Constants.BGP_FLOWSPEC_IP_PROTO:
                                flowSpecComponent = BgpFsIpProtocol.read(tempBuf);
                                break;
                            case Constants.BGP_FLOWSPEC_PORT:
                                flowSpecComponent = BgpFsPortNum.read(tempBuf);
                                break;
                            case Constants.BGP_FLOWSPEC_DST_PORT:
                                flowSpecComponent = BgpFsDestinationPortNum.read(tempBuf);
                                break;
                            case Constants.BGP_FLOWSPEC_SRC_PORT:
                                flowSpecComponent = BgpFsSourcePortNum.read(tempBuf);
                                break;
                            case Constants.BGP_FLOWSPEC_ICMP_TP:
                                flowSpecComponent = BgpFsIcmpType.read(tempBuf);
                                break;
                            case Constants.BGP_FLOWSPEC_ICMP_CD:
                                flowSpecComponent = BgpFsIcmpCode.read(tempBuf);
                                break;
                            case Constants.BGP_FLOWSPEC_TCP_FLAGS:
                                flowSpecComponent = BgpFsTcpFlags.read(tempBuf);
                                break;
                            case Constants.BGP_FLOWSPEC_PCK_LEN:
                                flowSpecComponent = BgpFsPacketLength.read(tempBuf);
                                break;
                            case Constants.BGP_FLOWSPEC_DSCP:
                                flowSpecComponent = BgpFsDscpValue.read(tempBuf);
                                break;
                            case Constants.BGP_FLOWSPEC_FRAGMENT:
                                flowSpecComponent = BgpFsFragment.read(tempBuf);
                                break;
                            default:
                                log.debug("flow spec type not supported" + type);
                                break;
                            }
                            flowSpecComponents.add(flowSpecComponent);
                        }
                    }
                }
                BgpFlowSpecNlri flowSpecDetails = new BgpFlowSpecNlri(flowSpecComponents);
                flowSpecDetails.setRouteDistinguiher(routeDistinguisher);
                return new MpUnReachNlri(flowSpecDetails, afi, safi);
            } else if ((afi == Constants.AFI_EVPN_VALUE)
                    && (safi == Constants.SAFI_EVPN_VALUE)) {
                List<BgpEvpnNlri> eVpnComponents = null;
                while (tempCb.readableBytes() > 0) {
                    BgpEvpnNlri eVpnComponent = BgpEvpnNlriImpl.read(tempCb);
                    eVpnComponents = new LinkedList<>();
                    eVpnComponents.add(eVpnComponent);
                    log.info("=====evpn Component is {} ======", eVpnComponent);
                }

                return new MpUnReachNlri(eVpnComponents, afi, safi);
            } else {
                //TODO: check with the values got from capability
                throw new BgpParseException("Not Supporting afi " + afi + "safi " + safi);
            }
        }
        return new MpUnReachNlri(mpUnReachNlri, afi, safi,
                                 parseFlags.getLength());
    }

    @Override
    public short getType() {
        return MPUNREACHNLRI_TYPE;
    }

    /**
     * Returns SAFI.
     *
     * @return SAFI
     */
    public byte safi() {
        return this.safi;
    }

    /**
     * Returns AFI.
     *
     * @return AFI
     */
    public short afi() {
        return this.afi;
    }

    /**
     * Returns list of MpUnReach Nlri.
     *
     * @return list of MpUnReach Nlri
     */
    public List<BgpLSNlri> mpUnReachNlri() {
        return this.mpUnReachNlri;
    }

    /**
     * Returns whether MpReachNlri is present.
     *
     * @return whether MpReachNlri is present
     */
    public boolean isMpUnReachNlriSet() {
        return this.isMpUnReachNlri;
    }

    /**
     * Returns length of MpUnReach.
     *
     * @return length of MpUnReach
     */
    public int mpUnReachNlriLen() {
        return this.length;
    }

    @Override
    public int write(ChannelBuffer cb) {
        int iLenStartIndex = cb.writerIndex();
        if ((afi == Constants.AFI_FLOWSPEC_VALUE) && ((safi == Constants.SAFI_FLOWSPEC_VALUE) ||
            (safi == Constants.VPN_SAFI_FLOWSPEC_VALUE))) {
            List<BgpValueType> flowSpec = bgpFlowSpecNlri.flowSpecComponents();
            ListIterator<BgpValueType> listIterator = flowSpec.listIterator();
            boolean isAllFlowTypesIdentical = true;

            cb.writeByte(FLAGS);
            cb.writeByte(MPUNREACHNLRI_TYPE);

            int mpUnReachIndx = cb.writerIndex();
            cb.writeShort(0);

            cb.writeShort(afi);
            cb.writeByte(safi);

            if (bgpFlowSpecNlri.routeDistinguisher() != null) {
                cb.writeLong(bgpFlowSpecNlri.routeDistinguisher().getRouteDistinguisher());
            }

            BgpValueType tlv1 = null;
            if (listIterator.hasNext()) {
                tlv1 = listIterator.next();
            }
            while (listIterator.hasNext()) {
                BgpValueType tlv = listIterator.next();
                if (tlv.getType() != tlv1.getType()) {
                    isAllFlowTypesIdentical = false;
                    break;
                }
            }

            if (isAllFlowTypesIdentical) {
                BgpFlowSpecNlri.updateBufferIdenticalFlowTypes(cb, bgpFlowSpecNlri());
            } else {
                BgpFlowSpecNlri.updateBufferNonIdenticalFlowTypes(cb, bgpFlowSpecNlri());
            }
            int fsNlriLen = cb.writerIndex() - mpUnReachIndx;
            cb.setShort(mpUnReachIndx, (short) (fsNlriLen - 2));
        } else if ((afi == Constants.AFI_EVPN_VALUE)
                && (safi == Constants.SAFI_EVPN_VALUE)) {

            cb.writeByte(FLAGS);
            cb.writeByte(MPUNREACHNLRI_TYPE);

            int mpUnReachDataIndex = cb.writerIndex();
            cb.writeShort(0);
            cb.writeShort(afi);
            cb.writeByte(safi);

            for (BgpEvpnNlri element : evpnNlri) {
                short routeType = element.getType();
                switch (routeType) {
                    case Constants.BGP_EVPN_MAC_IP_ADVERTISEMENT:
                        cb.writeByte(element.getType());
                        int iSpecStartIndex = cb.writerIndex();
                        cb.writeByte(0);
                        BgpEvpnRouteType2Nlri macIpAdvNlri =
                                (BgpEvpnRouteType2Nlri) element
                                        .getNlri();

                        macIpAdvNlri.write(cb);
                        cb.setByte(iSpecStartIndex, (short) (cb.writerIndex()
                                - iSpecStartIndex - 1));
                        break;
                    case Constants.BGP_EVPN_ETHERNET_AUTO_DISCOVERY:
                        break;
                    case Constants.BGP_EVPN_INCLUSIVE_MULTICASE_ETHERNET:
                        break;
                    case Constants.BGP_EVPN_ETHERNET_SEGMENT:
                        break;
                    default:
                        break;
                }
            }

            int evpnNlriLen = cb.writerIndex() - mpUnReachDataIndex;
            cb.setShort(mpUnReachDataIndex, (short) (evpnNlriLen - 2));
        }

        return cb.writerIndex() - iLenStartIndex;
    }

    @Override
    public int compareTo(Object o) {
        // TODO Auto-generated method stub
        return 0;
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass()).omitNullValues()
                .add("mpReachNlri", mpUnReachNlri)
                .add("bgpFlowSpecNlri", bgpFlowSpecNlri)
                .add("afi", afi)
                .add("safi", safi)
                .add("length", length)
                .toString();
    }
}