/*
 * 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.bgp.controller.impl;

import org.onosproject.bgpio.protocol.linkstate.PathAttrNlriDetailsLocalRib;
import org.onosproject.bgpio.types.AsPath;
import org.onosproject.bgpio.types.BgpValueType;
import org.onosproject.bgpio.types.LocalPref;
import org.onosproject.bgpio.types.Med;
import org.onosproject.bgpio.types.Origin;
import org.onosproject.bgpio.types.Origin.OriginType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Comparator;
import java.util.List;
import java.util.ListIterator;

/**
 * Implementation of BGP best path Selection process.
 */
public final class BgpSelectionAlgo implements Comparator<PathAttrNlriDetailsLocalRib> {
    private static final Logger log = LoggerFactory.getLogger(BgpSelectionAlgo.class);
    LocalPref obj1LocPref = null;
    AsPath obj1Aspath = null;
    Origin obj1Origin = null;
    Med obj1Med = null;
    LocalPref obj2LocPref = null;
    AsPath obj2Aspath = null;
    Origin obj2Origin = null;
    Med obj2Med = null;

    @Override
    public int compare(PathAttrNlriDetailsLocalRib pathNlriDetails1, PathAttrNlriDetailsLocalRib pathNlriDetails2) {
        if (pathNlriDetails1 == null) {
            return -1;
        }
        if (pathNlriDetails2 == null) {
            return 1;
        }
        if (pathNlriDetails1.equals(pathNlriDetails2)) {
            return 0;
        }

        List<BgpValueType> o1 = pathNlriDetails1.localRibNlridetails().pathAttributes();
        List<BgpValueType> o2 = pathNlriDetails2.localRibNlridetails().pathAttributes();
        ListIterator<BgpValueType> listIteratorObj1 = o1.listIterator();
        ListIterator<BgpValueType> listIteratorObj2 = o2.listIterator();
        storeAttr(listIteratorObj1, listIteratorObj2);

        // prefer attribute with higher local preference
        if (obj1LocPref != null || obj2LocPref != null && (obj1LocPref != null && !obj1LocPref.equals(obj2LocPref))) {
            return compareLocalPref(obj1LocPref, obj2LocPref);
        }

        // prefer attribute with shortest Aspath
        if (!obj1Aspath.equals(obj2Aspath)) {
            Integer obj1Size = countASSize(obj1Aspath);
            Integer obj2Size = countASSize(obj2Aspath);
            if (obj1Size != obj2Size) {
                return compareAsPath(obj1Size, obj2Size);
            }
        }

        // prefer attribute with lowest origin type
        if (!obj1Origin.equals(obj2Origin)) {
            return compareOrigin(obj1Origin, obj2Origin);
        }

        // prefer attribute with lowest MED
        if (obj1Med != null || obj2Med != null && (obj1Med != null && !obj1Med.equals(obj2Med))) {
            return compareMed(obj1Med, obj2Med);
        }

        if ((pathNlriDetails1 != null || pathNlriDetails2 != null) && (pathNlriDetails1 != null && !pathNlriDetails1
                        .equals(pathNlriDetails2))) {
            return comparePeerDetails(pathNlriDetails1, pathNlriDetails2);
        }
        return 0;
    }

    /**
     * Compares local preference of two objects and returns object with higher preference.
     *
     * @param obj1LocPref local preference object1
     * @param obj2LocPref local preference object2
     * @return object with higher preference
     */
    int compareLocalPref(LocalPref obj1LocPref, LocalPref obj2LocPref) {
            return ((Integer) (obj1LocPref.localPref())).compareTo((Integer) (obj2LocPref.localPref()));
    }

    /**
     * Compares AsPath of two objects and returns object with shortest AsPath.
     *
     * @param obj1Size object1 AS count
     * @param obj2Size object2 AS count
     * @return object with shortest AsPath
     */
    int compareAsPath(Integer obj1Size, Integer obj2Size) {
            return obj1Size.compareTo(obj2Size);
    }

    /**
     * Compare Origin of two objects and returns object with lowest origin value.
     *
     * @param obj1Origin Origin object1
     * @param obj2Origin Origin object1
     * @return object with lowest origin value
     */
    int compareOrigin(Origin obj1Origin, Origin obj2Origin) {
        if (obj1Origin.origin() == OriginType.IGP) {
            return 1;
        }
        if (obj2Origin.origin() == OriginType.IGP) {
            return -1;
        }
        if (obj1Origin.origin() == OriginType.EGP) {
            return 1;
        } else {
            return -1;
        }
    }

    /**
     * Compare Med of two objects and returns object with lowestMed value.
     *
     * @param obj1Med Med object1
     * @param obj2Med Med object2
     * @return returns object with lowestMed value
     */
    int compareMed(Med obj1Med, Med obj2Med) {
        return ((Integer) (obj2Med.med())).compareTo((Integer) (obj1Med.med()));
    }

    /**
     * Compares EBGP over IBGP, BGP identifier value and peer address.
     *
     * @param pathNlriDetails1 PathAttrNlriDetailsLocalRib object1
     * @param pathNlriDetails2 PathAttrNlriDetailsLocalRib object2
     * @return object which as EBGP over IBGP, lowest BGP identifier value and lowest peer address
     */
    int comparePeerDetails(PathAttrNlriDetailsLocalRib pathNlriDetails1, PathAttrNlriDetailsLocalRib pathNlriDetails2) {
        // consider EBGP over IBGP
        if (pathNlriDetails1.isLocalRibIbgpSession() != pathNlriDetails2.isLocalRibIbgpSession()) {
            if (pathNlriDetails1 == null || pathNlriDetails1.isLocalRibIbgpSession()) {
                return -1;
            }
            if (pathNlriDetails2 == null || pathNlriDetails2.isLocalRibIbgpSession()) {
                return 1;
            }
        }
        // prefer lowest BGP identifier value.
        if (pathNlriDetails1.localRibIdentifier() != pathNlriDetails2.localRibIdentifier()) {
            return ((Integer) pathNlriDetails2.localRibIdentifier())
                    .compareTo(pathNlriDetails1.localRibIdentifier());
        }
        //prefer lowest peer address
        if (pathNlriDetails1.localRibIpAddress() != pathNlriDetails2.localRibIpAddress()) {
            return pathNlriDetails2.localRibIpAddress().compareTo(pathNlriDetails1.localRibIpAddress());
        }
        return 0;
    }

    /**
     * Returns ASes count of AsPath attribute , if AS_SET is present then count as 1.
     *
     * @param aspath object of AsPath
     * @return count of ASes
     */
    Integer countASSize(AsPath aspath) {
        boolean isASSet = false;
        int count = 0;
        if (!aspath.asPathSet().isEmpty()) {
            isASSet = true;
        }
        if (!aspath.asPathSeq().isEmpty()) {
            count = aspath.asPathSeq().size();
        }
        return isASSet ? ++count : count;
    }

    /**
     * Stores BGP basic attributes of two objects.
     *
     * @param listIteratorObj1 list iterator of object1
     * @param listIteratorObj2 list iterator of object2
     */
    void storeAttr(ListIterator<BgpValueType> listIteratorObj1, ListIterator<BgpValueType> listIteratorObj2) {
         while (listIteratorObj1.hasNext()) {
             BgpValueType pathAttributeObj1 = listIteratorObj1.next();
             switch (pathAttributeObj1.getType()) {
             case LocalPref.LOCAL_PREF_TYPE:
                 obj1LocPref = (LocalPref) pathAttributeObj1;
                 break;
             case AsPath.ASPATH_TYPE:
                 obj1Aspath = (AsPath) pathAttributeObj1;
                 break;
             case Origin.ORIGIN_TYPE:
                 obj1Origin = (Origin) pathAttributeObj1;
                 break;
             case Med.MED_TYPE:
                 obj1Med = (Med) pathAttributeObj1;
                 break;
             default:
                 log.debug("Got other type, Not required: " + pathAttributeObj1.getType());
             }
         }
         while (listIteratorObj2.hasNext()) {
             BgpValueType pathAttributeObj2 = listIteratorObj2.next();
             switch (pathAttributeObj2.getType()) {
             case LocalPref.LOCAL_PREF_TYPE:
                 obj2LocPref = (LocalPref) pathAttributeObj2;
                 break;
             case AsPath.ASPATH_TYPE:
                 obj2Aspath = (AsPath) pathAttributeObj2;
                 break;
             case Origin.ORIGIN_TYPE:
                 obj2Origin = (Origin) pathAttributeObj2;
                 break;
             case Med.MED_TYPE:
                 obj2Med = (Med) pathAttributeObj2;
                 break;
             default:
                 log.debug("Got other type, Not required: " + pathAttributeObj2.getType());
             }
        }
    }
}
