/*
 * 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 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;
    }
}