/*
 * Copyright 2015-present 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 static org.onlab.util.Tools.groupedThreads;

import java.lang.management.ManagementFactory;
import java.lang.management.RuntimeMXBean;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executors;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.bootstrap.ServerBootstrap;
import org.jboss.netty.channel.Channel;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.onosproject.bgp.controller.BgpController;
import org.onosproject.bgpio.protocol.BgpFactories;
import org.onosproject.bgpio.protocol.BgpFactory;
import org.onosproject.bgpio.protocol.BgpVersion;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * The main controller class. Handles all setup and network listeners - Distributed ownership control of bgp peer
 * through IControllerRegistryService
 */
public class Controller {

    private static final Logger log = LoggerFactory.getLogger(Controller.class);

    private static final BgpFactory FACTORY4 = BgpFactories.getFactory(BgpVersion.BGP_4);

    private ChannelGroup cg;
    public Channel serverChannel;

    // Configuration options
    private static final short BGP_PORT_NUM = 179;
    private static final short PORT_NUM_ZERO = 0;
    private static boolean isPortNumSet = false;
    private final int workerThreads = 16;
    private final int peerWorkerThreads = 16;

    // Start time of the controller
    private long systemStartTime;

    private NioServerSocketChannelFactory serverExecFactory;
    private NioClientSocketChannelFactory peerExecFactory;
    private static ClientBootstrap peerBootstrap;
    private BgpController bgpController;

    // Perf. related configuration
    private static final int SEND_BUFFER_SIZE = 4 * 1024 * 1024;

    /**
     * Constructor to initialize the values.
     *
     * @param bgpController bgp controller instance
     */
    public Controller(BgpController bgpController) {
        this.bgpController = bgpController;
    }

    /**
     * Returns factory version for processing BGP messages.
     *
     * @return instance of factory version
     */
    static BgpFactory getBgpMessageFactory4() {
        return FACTORY4;
    }

    /**
     * To get system start time.
     *
     * @return system start time in milliseconds
     */
    public long getSystemStartTime() {
        return (this.systemStartTime);
    }

    /**
     * Tell controller that we're ready to accept bgp peer connections.
     */
    public void run() {

        try {

            peerBootstrap = createPeerBootStrap();

            peerBootstrap.setOption("reuseAddr", true);
            peerBootstrap.setOption("child.keepAlive", true);
            peerBootstrap.setOption("child.tcpNoDelay", true);
            peerBootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);

            final ServerBootstrap bootstrap = createServerBootStrap();

            bootstrap.setOption("reuseAddr", true);
            bootstrap.setOption("child.keepAlive", true);
            bootstrap.setOption("child.tcpNoDelay", true);
            bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);

            ChannelPipelineFactory pfact = new BgpPipelineFactory(bgpController, true);

            bootstrap.setPipelineFactory(pfact);
            InetSocketAddress sa = new InetSocketAddress(getBgpPortNum());
            cg = new DefaultChannelGroup();
            serverChannel = bootstrap.bind(sa);
            cg.add(serverChannel);
            log.info("Listening for Peer connection on {}", sa);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * Creates server boot strap.
     *
     * @return ServerBootStrap
     */
    private ServerBootstrap createServerBootStrap() {

        if (workerThreads == 0) {
            serverExecFactory = new NioServerSocketChannelFactory(
                                    Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")),
                                    Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")));
            return new ServerBootstrap(serverExecFactory);
        } else {
            serverExecFactory = new NioServerSocketChannelFactory(
                                    Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")),
                                    Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")),
                                                                  workerThreads);
            return new ServerBootstrap(serverExecFactory);
        }
    }

    /**
     * Creates peer boot strap.
     *
     * @return ClientBootstrap
     */
    private ClientBootstrap createPeerBootStrap() {

        if (peerWorkerThreads == 0) {
            peerExecFactory = new NioClientSocketChannelFactory(
                              Executors.newCachedThreadPool(groupedThreads("onos/bgp", "boss-%d")),
                             Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")));
            return new ClientBootstrap(peerExecFactory);
        } else {
            peerExecFactory = new NioClientSocketChannelFactory(
                              Executors.newCachedThreadPool(groupedThreads("onos/bgp",  "boss-%d")),
                              Executors.newCachedThreadPool(groupedThreads("onos/bgp", "worker-%d")),
                                                                          peerWorkerThreads);
            return new ClientBootstrap(peerExecFactory);
        }
    }

    /**
     * Gets peer bootstrap.
     *
     * @return peer  bootstrap
     */
    public static ClientBootstrap peerBootstrap() {
        return peerBootstrap;
    }

    /**
     * Initialize internal data structures.
     */
    public void init() {
        // These data structures are initialized here because other
        // module's startUp() might be called before ours
        this.systemStartTime = System.currentTimeMillis();
    }

    /**
     * Gets run time memory.
     *
     * @return m run time memory
     */
    public Map<String, Long> getMemory() {
        Map<String, Long> m = new HashMap<>();
        Runtime runtime = Runtime.getRuntime();
        m.put("total", runtime.totalMemory());
        m.put("free", runtime.freeMemory());
        return m;
    }

    /**
     * Gets UP time.
     *
     * @return UP time
     */
    public Long getUptime() {
        RuntimeMXBean rb = ManagementFactory.getRuntimeMXBean();
        return rb.getUptime();
    }

    /**
     * Starts the BGP controller.
     */
    public void start() {
        log.info("Started");
        this.init();
        this.run();
    }

    /**
     * Stops the BGP controller.
     */
    public void stop() {
        log.info("Stopped");
        serverExecFactory.shutdown();
        peerExecFactory.shutdown();
        cg.close();
    }

    /**
     * Returns port number.
     *
     * @return port number
     */
    public static short getBgpPortNum() {
        if (isPortNumSet) {
            return PORT_NUM_ZERO;
        }
        return BGP_PORT_NUM;
    }

    /**
     * sets the isPortNumSet as true.
     */
    public void setBgpPortNum() {
        isPortNumSet = true;
    }
}