/*
 * Copyright 2015 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();
    }
}
