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

import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Modified;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelException;
import org.jboss.netty.channel.ChannelFactory;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip4Prefix;
import org.onlab.packet.Ip6Prefix;
import org.onlab.packet.IpPrefix;
import org.onosproject.cluster.ClusterService;
import org.onosproject.routeservice.Route;
import org.onosproject.routeservice.RouteAdminService;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Collection;
import java.util.Dictionary;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import static java.util.concurrent.Executors.newCachedThreadPool;
import static org.onlab.util.Tools.groupedThreads;

/**
 * BGP Session Manager class.
 */
@Component(immediate = true, enabled = false)
@Service
public class BgpSessionManager implements BgpInfoService {
    private static final Logger log =
            LoggerFactory.getLogger(BgpSessionManager.class);

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected RouteAdminService routeService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ClusterService clusterService;

    boolean isShutdown = true;
    private Channel serverChannel;     // Listener for incoming BGP connections
    private ServerBootstrap serverBootstrap;
    private ChannelGroup allChannels = new DefaultChannelGroup();
    private ConcurrentMap<SocketAddress, BgpSession> bgpSessions =
            new ConcurrentHashMap<>();
    private Ip4Address myBgpId;        // Same BGP ID for all peers

    private BgpRouteSelector bgpRouteSelector;
    private ConcurrentMap<Ip4Prefix, BgpRouteEntry> bgpRoutes4 =
            new ConcurrentHashMap<>();
    private ConcurrentMap<Ip6Prefix, BgpRouteEntry> bgpRoutes6 =
            new ConcurrentHashMap<>();

    private static final int DEFAULT_BGP_PORT = 2000;
    private int bgpPort;

    @Activate
    protected void activate(ComponentContext context) {
        bgpRouteSelector = new BgpRouteSelector(this, clusterService);
        readComponentConfiguration(context);
        start();
        log.info("BgpSessionManager started");
    }

    @Deactivate
    protected void deactivate() {
        stop();
        log.info("BgpSessionManager stopped");
    }

    /**
     * Extracts properties from the component configuration context.
     *
     * @param context the component context
     */
    private void readComponentConfiguration(ComponentContext context) {
        Dictionary<?, ?> properties = context.getProperties();
        try {
            String strPort = (String) properties.get("bgpPort");
            if (strPort != null) {
                bgpPort = Integer.parseInt(strPort);
            } else {
                bgpPort = DEFAULT_BGP_PORT;
            }
        } catch (NumberFormatException | ClassCastException e) {
            bgpPort = DEFAULT_BGP_PORT;
        }
        log.debug("BGP port is set to {}", bgpPort);
    }

    @Modified
    public void modified(ComponentContext context) {
        // Blank @Modified method to catch modifications to the context.
        // If no @Modified method exists, it seems @Activate is called again
        // when the context is modified.
    }

    /**
     * Checks whether the BGP Session Manager is shutdown.
     *
     * @return true if the BGP Session Manager is shutdown, otherwise false
     */
    boolean isShutdown() {
        return this.isShutdown;
    }

    /**
     * Gets the BGP sessions.
     *
     * @return the BGP sessions
     */
    @Override
    public Collection<BgpSession> getBgpSessions() {
        return bgpSessions.values();
    }

    /**
     * Gets the selected IPv4 BGP routes among all BGP sessions.
     *
     * @return the selected IPv4 BGP routes among all BGP sessions
     */
    @Override
    public Collection<BgpRouteEntry> getBgpRoutes4() {
        return bgpRoutes4.values();
    }

    /**
     * Gets the selected IPv6 BGP routes among all BGP sessions.
     *
     * @return the selected IPv6 BGP routes among all BGP sessions
     */
    @Override
    public Collection<BgpRouteEntry> getBgpRoutes6() {
        return bgpRoutes6.values();
    }

    /**
     * Finds a BGP route for a prefix. The prefix can be either IPv4 or IPv6.
     *
     * @param prefix the prefix to use
     * @return the BGP route if found, otherwise null
     */
    BgpRouteEntry findBgpRoute(IpPrefix prefix) {
        if (prefix.isIp4()) {
            return bgpRoutes4.get(prefix.getIp4Prefix());               // IPv4
        }
        return bgpRoutes6.get(prefix.getIp6Prefix());                   // IPv6
    }

    /**
     * Adds a BGP route. The route can be either IPv4 or IPv6.
     *
     * @param bgpRouteEntry the BGP route entry to use
     */
    void addBgpRoute(BgpRouteEntry bgpRouteEntry) {
        if (bgpRouteEntry.isIp4()) {
            bgpRoutes4.put(bgpRouteEntry.prefix().getIp4Prefix(),       // IPv4
                           bgpRouteEntry);
        } else {
            bgpRoutes6.put(bgpRouteEntry.prefix().getIp6Prefix(),       // IPv6
                           bgpRouteEntry);
        }
    }

    /**
     * Removes a BGP route for a prefix. The prefix can be either IPv4 or IPv6.
     *
     * @param prefix the prefix to use
     * @return true if the route was found and removed, otherwise false
     */
    boolean removeBgpRoute(IpPrefix prefix) {
        if (prefix.isIp4()) {
            return (bgpRoutes4.remove(prefix.getIp4Prefix()) != null);  // IPv4
        }
        return (bgpRoutes6.remove(prefix.getIp6Prefix()) != null);      // IPv6
    }

    /**
     * Adds the channel for a BGP session.
     *
     * @param channel the channel to add
     */
    void addSessionChannel(Channel channel) {
        allChannels.add(channel);
    }

    /**
     * Removes the channel for a BGP session.
     *
     * @param channel the channel to remove
     */
    void removeSessionChannel(Channel channel) {
        allChannels.remove(channel);
    }

    /**
     * Processes the connection from a BGP peer.
     *
     * @param bgpSession the BGP session for the peer
     * @return true if the connection can be established, otherwise false
     */
    boolean peerConnected(BgpSession bgpSession) {

        // Test whether there is already a session from the same remote
        if (bgpSessions.get(bgpSession.remoteInfo().address()) != null) {
            return false;               // Duplicate BGP session
        }
        bgpSessions.put(bgpSession.remoteInfo().address(), bgpSession);

        //
        // If the first connection, set my BGP ID to the local address
        // of the socket.
        //
        if (bgpSession.localInfo().address() instanceof InetSocketAddress) {
            InetAddress inetAddr =
                ((InetSocketAddress) bgpSession.localInfo().address()).getAddress();
            Ip4Address ip4Address = Ip4Address.valueOf(inetAddr.getAddress());
            updateMyBgpId(ip4Address);
        }
        return true;
    }

    /**
     * Processes the disconnection from a BGP peer.
     *
     * @param bgpSession the BGP session for the peer
     */
    void peerDisconnected(BgpSession bgpSession) {
        bgpSessions.remove(bgpSession.remoteInfo().address());
    }

    /**
     * Conditionally updates the local BGP ID if it wasn't set already.
     * <p/>
     * NOTE: A BGP instance should use same BGP ID across all BGP sessions.
     *
     * @param ip4Address the IPv4 address to use as BGP ID
     */
    private synchronized void updateMyBgpId(Ip4Address ip4Address) {
        if (myBgpId == null) {
            myBgpId = ip4Address;
            log.debug("BGP: My BGP ID is {}", myBgpId);
        }
    }

    /**
     * Gets the local BGP Identifier as an IPv4 address.
     *
     * @return the local BGP Identifier as an IPv4 address
     */
    Ip4Address getMyBgpId() {
        return myBgpId;
    }

    /**
     * Gets the BGP Route Selector.
     *
     * @return the BGP Route Selector
     */
    BgpRouteSelector getBgpRouteSelector() {
        return bgpRouteSelector;
    }

    /**
     * Sends updates routes to the route service.
     *
     * @param updates routes to update
     */
    void update(Collection<Route> updates) {
        routeService.update(updates);
    }

    /**
     * Sends withdrawn routes to the routes service.
     *
     * @param withdraws routes to withdraw
     */
    void withdraw(Collection<Route> withdraws) {
        routeService.withdraw(withdraws);
    }


    public void start() {
        log.debug("BGP Session Manager start.");
        isShutdown = false;

        ChannelFactory channelFactory = new NioServerSocketChannelFactory(
                newCachedThreadPool(groupedThreads("onos/bgp", "sm-boss-%d", log)),
                newCachedThreadPool(groupedThreads("onos/bgp", "sm-worker-%d", log)));
        ChannelPipelineFactory pipelineFactory = () -> {
            // Allocate a new session per connection
            BgpSession bgpSessionHandler =
                    new BgpSession(BgpSessionManager.this);
            BgpFrameDecoder bgpFrameDecoder =
                    new BgpFrameDecoder(bgpSessionHandler);

            // Setup the processing pipeline
            ChannelPipeline pipeline = Channels.pipeline();
            pipeline.addLast("BgpFrameDecoder", bgpFrameDecoder);
            pipeline.addLast("BgpSession", bgpSessionHandler);
            return pipeline;
        };
        InetSocketAddress listenAddress =
                new InetSocketAddress(bgpPort);

        serverBootstrap = new ServerBootstrap(channelFactory);
        // serverBootstrap.setOptions("reuseAddr", true);
        serverBootstrap.setOption("child.keepAlive", true);
        serverBootstrap.setOption("child.tcpNoDelay", true);
        serverBootstrap.setPipelineFactory(pipelineFactory);
        try {
            serverChannel = serverBootstrap.bind(listenAddress);
            allChannels.add(serverChannel);
        } catch (ChannelException e) {
            log.debug("Exception binding to BGP port {}: ",
                      listenAddress.getPort(), e);
        }
    }

    public void stop() {
        isShutdown = true;
        allChannels.close().awaitUninterruptibly();
        serverBootstrap.releaseExternalResources();
    }
}
