/*
 * Copyright 2018-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.xmpp.core.ctl;

import com.google.common.base.Strings;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.AbstractChannel;
import io.netty.channel.Channel;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.epoll.EpollEventLoopGroup;
import io.netty.channel.epoll.EpollSocketChannel;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import org.onosproject.xmpp.core.XmppDeviceFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.InetSocketAddress;
import java.util.Dictionary;

import static org.onlab.util.Tools.get;

/**
 *  The XMPP server class. Starts XMPP server and listens to new XMPP device TCP connections.
 */
public class XmppServer {

    protected static final Logger log = LoggerFactory.getLogger(XmppServer.class);

    protected Integer port = 5259;

    protected Channel channel;
    protected EventLoopGroup eventLoopGroup;
    protected Class<? extends AbstractChannel> channelClass;


    /**
     * Initializes XMPP server.
     */
    public void init() {

    }

    /**
     * Runs XMPP server thread.
     * @param deviceFactory XMPP devices factory
     */
    public void run(XmppDeviceFactory deviceFactory) {
        try {
            final ServerBootstrap bootstrap = createServerBootStrap(deviceFactory);

            InetSocketAddress socketAddress = new InetSocketAddress(port);
            channel = bootstrap.bind(socketAddress).sync().channel().closeFuture().channel();

            log.info("Listening for device connections on {}", socketAddress);

        } catch (Exception ex) {
            throw new RuntimeException(ex);
        }
    }

    private ServerBootstrap createServerBootStrap(XmppDeviceFactory deviceFactory) {

        ServerBootstrap bootstrap = new ServerBootstrap();
        configureBootstrap(bootstrap);
        initEventLoopGroup();

        bootstrap.group(eventLoopGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new XmppChannelInitializer(deviceFactory));

        return bootstrap;
    }

    /**
     * Initializes event loop group.
     */
    private void initEventLoopGroup() {

        // try to use EpollEventLoopGroup if possible,
        // if OS does not support native Epoll, fallback to use netty NIO
        try {
            eventLoopGroup = new EpollEventLoopGroup();
            channelClass = EpollSocketChannel.class;
            return;
        } catch (Error e) {
            log.debug("Failed to initialize native (epoll) transport. "
                    + "Reason: {}. Proceeding with NIO event group.", e);
        }
        eventLoopGroup = new NioEventLoopGroup();
        channelClass = NioServerSocketChannel.class;
    }

    private void configureBootstrap(ServerBootstrap bootstrap) {
        bootstrap.option(ChannelOption.TCP_NODELAY, true);
        bootstrap.option(ChannelOption.ALLOCATOR, PooledByteBufAllocator.DEFAULT);
        bootstrap.option(ChannelOption.SO_RCVBUF, 2048);
    }

    /**
     * TLS/SSL setup. If needed.
     */
    private void initTls() {
        // TODO: add support for TLS/SSL
    }

    /**
     * Sets configuration parameters defined via ComponentConfiguration subsystem.
     * @param properties properties to be set
     */
    public void setConfiguration(Dictionary<?, ?> properties) {
        String port = get(properties, "xmppPort");
        if (!Strings.isNullOrEmpty(port)) {
            this.port = Integer.parseInt(port);
        }
        log.debug("XMPP port set to {}", this.port);
    }

    /**
     * Starts XMPP server.
     *
     * @param deviceFactory XMPP devices factory
     */
    public void start(XmppDeviceFactory deviceFactory) {
        log.info("XMPP Server has started.");
        this.run(deviceFactory);
    }

    /**
     * Stops XMPP server.
     *
     */
    public void stop() {
        log.info("Stopping XMPP I/O");
        channel.close();
        eventLoopGroup.shutdownGracefully();
    }
}
