/*
 * Copyright 2015-present 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.bgpio.protocol.ver4;

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

import org.jboss.netty.buffer.ChannelBuffer;
import org.onosproject.bgpio.exceptions.BgpParseException;
import org.onosproject.bgpio.types.As4Path;
import org.onosproject.bgpio.types.AsPath;
import org.onosproject.bgpio.types.BgpErrorType;
import org.onosproject.bgpio.types.BgpExtendedCommunity;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.LinkStateAttributes;
import org.onosproject.bgpio.types.LocalPref;
import org.onosproject.bgpio.types.Med;
import org.onosproject.bgpio.types.NextHop;
import org.onosproject.bgpio.types.Origin;
import org.onosproject.bgpio.types.MpReachNlri;
import org.onosproject.bgpio.types.MpUnReachNlri;
import org.onosproject.bgpio.util.UnSupportedAttribute;
import org.onosproject.bgpio.util.Validation;
import org.onosproject.bgpio.util.Constants;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.MoreObjects;

/**
 * Provides Implementation of BGP Path Attribute.
 */
public class BgpPathAttributes {

    /* Path attribute:
           <attribute type, attribute length, attribute value>

           0                   1
           0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           |  Attr. Flags  |Attr. Type Code|
           +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
           REFERENCE : RFC 4271
    */
    protected static final Logger log = LoggerFactory.getLogger(BgpPathAttributes.class);

    public static final int LINK_STATE_ATTRIBUTE_TYPE = 29;
    public static final int MPREACHNLRI_TYPE = 14;
    public static final int MPUNREACHNLRI_TYPE = 15;
    public static final int EXTENDED_COMMUNITY_TYPE = 16;

    private final List<BgpValueType> pathAttribute;

    /**
     * Initialize parameter.
     */
    public BgpPathAttributes() {
        this.pathAttribute = null;
    }

    /**
     * Constructor to initialize parameters for BGP path attributes.
     *
     * @param pathAttribute list of path attributes
     */
    public BgpPathAttributes(List<BgpValueType> pathAttribute) {
        this.pathAttribute = pathAttribute;
    }

    /**
     * Returns list of path attributes.
     *
     * @return list of path attributes
     */
    public List<BgpValueType> pathAttributes() {
        return this.pathAttribute;
    }

    /**
     * Reads from channelBuffer and parses BGP path attributes.
     *
     * @param cb channelBuffer
     * @return object of BgpPathAttributes
     * @throws BgpParseException while parsing BGP path attributes
     */
    public static BgpPathAttributes read(ChannelBuffer cb)
            throws BgpParseException {

        BgpValueType pathAttribute = null;
        List<BgpValueType> pathAttributeList = new LinkedList<>();
        boolean isOrigin = false;
        boolean isAsPath = false;
        boolean isNextHop = false;
        boolean isMpReach = false;
        boolean isMpUnReach = false;
        while (cb.readableBytes() > 0) {
            cb.markReaderIndex();
            byte flags = cb.readByte();
            byte typeCode = cb.readByte();
            cb.resetReaderIndex();
            switch (typeCode) {
            case Origin.ORIGIN_TYPE:
                pathAttribute = Origin.read(cb);
                isOrigin = ((Origin) pathAttribute).isOriginSet();
                break;
            case AsPath.ASPATH_TYPE:
                pathAttribute = AsPath.read(cb);
                isAsPath = ((AsPath) pathAttribute).isaspathSet();
                break;
            case As4Path.AS4PATH_TYPE:
                pathAttribute = As4Path.read(cb);
                break;
            case NextHop.NEXTHOP_TYPE:
                pathAttribute = NextHop.read(cb);
                isNextHop = ((NextHop) pathAttribute).isNextHopSet();
                break;
            case Med.MED_TYPE:
                pathAttribute = Med.read(cb);
                break;
            case LocalPref.LOCAL_PREF_TYPE:
                pathAttribute = LocalPref.read(cb);
                break;
            case MpReachNlri.MPREACHNLRI_TYPE:
                pathAttribute = MpReachNlri.read(cb);
                isMpReach = ((MpReachNlri) pathAttribute).isMpReachNlriSet();
                break;
            case MpUnReachNlri.MPUNREACHNLRI_TYPE:
                pathAttribute = MpUnReachNlri.read(cb);
                isMpUnReach = ((MpUnReachNlri) pathAttribute)
                        .isMpUnReachNlriSet();
                break;
            case LINK_STATE_ATTRIBUTE_TYPE:
                pathAttribute = LinkStateAttributes.read(cb);
                break;
            case EXTENDED_COMMUNITY_TYPE:
                pathAttribute = BgpExtendedCommunity.read(cb);
                break;
            default:
                //skip bytes for unsupported attribute types
                UnSupportedAttribute.read(cb);
            }
            pathAttributeList.add(pathAttribute);
        }

        checkMandatoryAttr(isOrigin, isAsPath, isNextHop, isMpReach, isMpUnReach);
        //TODO:if mp_reach or mp_unreach not present ignore the packet
        return new BgpPathAttributes(pathAttributeList);
    }

    /**
     * Write path attributes to channelBuffer.
     *
     * @param cb channelBuffer
     * @return object of BgpPathAttributes
     * @throws BgpParseException while parsing BGP path attributes
     */
    public int write(ChannelBuffer cb)
            throws BgpParseException {

        if (pathAttribute == null) {
            return 0;
        }
        int iLenStartIndex = cb.writerIndex();

        ListIterator<BgpValueType> iterator = pathAttribute.listIterator();

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

        while (iterator.hasNext()) {

            BgpValueType attr = iterator.next();

            switch (attr.getType()) {
            case Origin.ORIGIN_TYPE:
                Origin origin = (Origin) attr;
                origin.write(cb);
                break;
            case AsPath.ASPATH_TYPE:
                AsPath asPath = (AsPath) attr;
                asPath.write(cb);
                break;
            case As4Path.AS4PATH_TYPE:
                As4Path as4Path = (As4Path) attr;
                as4Path.write(cb);
                break;
            case NextHop.NEXTHOP_TYPE:
                NextHop nextHop = (NextHop) attr;
                nextHop.write(cb);
                break;
            case Med.MED_TYPE:
                Med med = (Med) attr;
                med.write(cb);
                break;
            case LocalPref.LOCAL_PREF_TYPE:
                LocalPref localPref = (LocalPref) attr;
                localPref.write(cb);
                break;
            case Constants.BGP_EXTENDED_COMMUNITY:
                BgpExtendedCommunity extendedCommunity = (BgpExtendedCommunity) attr;
                extendedCommunity.write(cb);
                break;
            case MpReachNlri.MPREACHNLRI_TYPE:
                MpReachNlri mpReach = (MpReachNlri) attr;
                mpReach.write(cb);
                break;
            case MpUnReachNlri.MPUNREACHNLRI_TYPE:
                MpUnReachNlri mpUnReach = (MpUnReachNlri) attr;
                mpUnReach.write(cb);
                break;
            case LINK_STATE_ATTRIBUTE_TYPE:
                LinkStateAttributes linkState = (LinkStateAttributes) attr;
                linkState.write(cb);
                break;
            default:
                return cb.writerIndex() - iLenStartIndex;
            }
        }

        int pathAttrLen = cb.writerIndex() - pathAttributeIndx;
        cb.setShort(pathAttributeIndx, (short) (pathAttrLen - 2));
        return cb.writerIndex() - iLenStartIndex;
    }

    /**
     * Checks mandatory attributes are presents, if not present throws exception.
     *
     * @param isOrigin say whether origin attribute is present
     * @param isAsPath say whether aspath attribute is present
     * @param isNextHop say whether nexthop attribute is present
     * @param isMpReach say whether mpreach attribute is present
     * @param isMpUnReach say whether mpunreach attribute is present
     * @throws BgpParseException if mandatory path attribute is not present
     */
    public static void checkMandatoryAttr(boolean isOrigin, boolean isAsPath,
            boolean isNextHop, boolean isMpReach, boolean isMpUnReach)
            throws BgpParseException {
        // Mandatory attributes validation not required for MP_UNREACH
        if (isMpUnReach) {
            return;
        }

        if (!isOrigin) {
            log.debug("Mandatory Attributes not Present");
            Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
                    BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
                    Origin.ORIGIN_TYPE);
        }
        if (!isAsPath) {
            log.debug("Mandatory Attributes not Present");
            Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
                    BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
                    AsPath.ASPATH_TYPE);
        }
        if (!isMpUnReach && !isMpReach && !isNextHop) {
            log.debug("Mandatory Attributes not Present");
            Validation.validateType(BgpErrorType.UPDATE_MESSAGE_ERROR,
                    BgpErrorType.MISSING_WELLKNOWN_ATTRIBUTE,
                    NextHop.NEXTHOP_TYPE);
        }
    }

    @Override
    public String toString() {
        return MoreObjects.toStringHelper(getClass())
                .add("pathAttribute", pathAttribute)
                .toString();
    }
}
