/*
 * Copyright 2017-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.incubator.net.routing;

import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.MacAddress;

import java.util.List;
import java.util.Objects;

import static com.google.common.base.MoreObjects.toStringHelper;
import static com.google.common.base.Preconditions.checkNotNull;

/**
 * Represents a evpn route.
 */
public class EvpnRoute {


    /**
     * Source of the route.
     */
    public enum Source {
        /**
         * Route came from app source.
         */
        LOCAL,

        /**
         * Route came from remote bgp peer source.
         */
        REMOTE,
    }

    private final Source source;
    private final MacAddress prefixMac;
    private final IpPrefix prefix;
    private final IpAddress nextHop;
    private final RouteDistinguisher rd;
    private List<VpnRouteTarget> importRtList;
    private List<VpnRouteTarget> exportRtList;
    private final Label label;

    /**
     * Constructor to initialize the parameters.
     *
     * @param source       route source
     * @param prefixMac    mac address
     * @param prefix       ip address
     * @param prefix
     * @param nextHop      evpn nexthop
     * @param rd           route distinguisher
     * @param importRtList import route targets
     * @param exportRtList export route targets
     * @param label        evpn route label
     */
    public EvpnRoute(Source source,
                     MacAddress prefixMac,
                     IpPrefix prefix,
                     IpAddress nextHop,
                     RouteDistinguisher rd,
                     List<VpnRouteTarget> importRtList,
                     List<VpnRouteTarget> exportRtList,
                     Label label) {

        checkNotNull(prefixMac);
        checkNotNull(prefix);
        //checkNotNull(nextHop);//next hop can be null in case of MP un reach.
        checkNotNull(rd);
        checkNotNull(label);
        this.source = checkNotNull(source);
        this.prefix = prefix;
        this.prefixMac = prefixMac;
        this.nextHop = nextHop;
        this.rd = rd;
        this.importRtList = importRtList;
        this.exportRtList = exportRtList;
        this.label = label;
    }

    /**
     * Constructor to initialize the parameters.
     *
     * @param source       route source
     * @param prefixMac    mac address
     * @param prefix       ip address
     * @param nextHop      evpn nexthop
     * @param rdToString   route distinguisher
     * @param importRtList import route targets
     * @param exportRtList export route targets
     * @param labelToInt   evpn route label
     * @param prefix
     */
    public EvpnRoute(Source source,
                     MacAddress prefixMac,
                     IpPrefix prefix,
                     IpAddress nextHop,
                     String rdToString,
                     List<VpnRouteTarget> importRtList,
                     List<VpnRouteTarget> exportRtList,
                     int labelToInt) {
        checkNotNull(prefixMac);
        checkNotNull(prefix);
        //checkNotNull(nextHop); //next hop can be null in case of MP un reach.
        checkNotNull(labelToInt);
        this.source = checkNotNull(source);
        this.prefix = prefix;
        this.prefixMac = prefixMac;
        this.nextHop = nextHop;
        this.rd = RouteDistinguisher.routeDistinguisher(rdToString);
        this.importRtList = importRtList;
        this.exportRtList = exportRtList;
        this.label = Label.label(labelToInt);
    }

    /**
     * Returns the route source.
     *
     * @return route source
     */
    public Source source() {
        return source;
    }

    /**
     * Returns the address.
     *
     * @return MacAddress
     */
    public MacAddress prefixMac() {
        return prefixMac;
    }

    /**
     * Returns the IPv4 address.
     *
     * @return Ip4Address
     */
    public IpPrefix prefixIp() {
        return prefix;
    }

    /**
     * Returns the IPv4 address.
     *
     * @return Ip4Address
     */
    public EvpnPrefix evpnPrefix() {
        return new EvpnPrefix(rd, prefixMac,
                              prefix);
    }


    /**
     * Returns the next hop IP address.
     *
     * @return Ip4Address
     */
    public IpAddress ipNextHop() {
        return nextHop;
    }

    public EvpnNextHop nextHop() {
        return EvpnNextHop.evpnNextHop(nextHop,
                                       importRtList,
                                       exportRtList,
                                       label);
    }

    /**
     * Returns the routeDistinguisher.
     *
     * @return RouteDistinguisher
     */
    public RouteDistinguisher routeDistinguisher() {
        return rd;
    }

    /**
     * Returns the Route targets.
     *
     * @return RouteTarget List
     */

    public List<VpnRouteTarget> importRouteTarget() {
        return importRtList;
    }

    /**
     * Returns the Route targets.
     *
     * @return RouteTarget List
     */
    public List<VpnRouteTarget> exportRouteTarget() {
        return exportRtList;
    }

    /**
     * Set import list.
     *
     * @param importRtList import list
     */
    public void setImportRtList(List<VpnRouteTarget> importRtList) {
        this.importRtList = importRtList;
    }

    /**
     * Set export list.
     *
     * @param exportRtList export list
     */
    public void setExportRtList(List<VpnRouteTarget> exportRtList) {
        this.exportRtList = exportRtList;
    }

    /**
     * Returns the label.
     *
     * @return Label
     */
    public Label label() {
        return label;
    }

    @Override
    public int hashCode() {
        return Objects.hash(prefixMac,
                            prefix,
                            nextHop,
                            rd,
                            importRtList,
                            exportRtList,
                            label);
    }

    @Override
    public boolean equals(Object other) {
        if (this == other) {
            return true;
        }

        if (!(other instanceof EvpnRoute)) {
            return false;
        }

        EvpnRoute that = (EvpnRoute) other;

        return Objects.equals(prefixMac, prefixMac)
                && Objects.equals(prefix, that.prefix)
                && Objects.equals(nextHop, that.nextHop)
                && Objects.equals(this.rd, that.rd)
                && Objects.equals(this.importRtList, that.importRtList)
                && Objects.equals(this.exportRtList, that.exportRtList)
                && Objects.equals(this.label, that.label);
    }

    @Override
    public String toString() {
        return toStringHelper(this)
                .add("prefixMac", prefixMac)
                .add("prefix", prefix)
                .add("nextHop", nextHop)
                .add("rd", this.rd)
                .add("import rt", this.importRtList)
                .add("export rt", this.exportRtList)
                .add("label", this.label)
                .toString();
    }
}
