/*
 * 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 java.net.InetSocketAddress;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.jboss.netty.bootstrap.ClientBootstrap;
import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.onosproject.bgp.controller.BgpCfg;
import org.onosproject.bgp.controller.BgpController;
import org.onosproject.bgp.controller.BgpPeerCfg;
import org.onosproject.bgp.controller.BgpConnectPeer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Implements connection initiation to peer on peer configuration and manage channel using netty channel handler.
 */
public class BgpConnectPeerImpl implements BgpConnectPeer {
    private static final Logger log = LoggerFactory.getLogger(BgpConnectPeerImpl.class);

    private ScheduledExecutorService connectExecutor = null;
    private final String peerHost;
    private static final int RETRY_INTERVAL = 4;
    private final int peerPort;
    private int connectRetryCounter = 0;
    private int connectRetryTime;
    private ChannelPipelineFactory pfact;
    private ClientBootstrap peerBootstrap;
    private BgpCfg bgpconfig;

    /**
     * Initialize timer and initiate pipeline factory.
     *
     * @param bgpController parent BGP controller
     * @param remoteHost remote host to connect
     * @param remotePort remote port to connect
     */
    public BgpConnectPeerImpl(BgpController bgpController, String remoteHost, int remotePort) {

        this.bgpconfig = bgpController.getConfig();
        this.pfact = new BgpPipelineFactory(bgpController, false);
        this.peerBootstrap = Controller.peerBootstrap();
        this.peerBootstrap.setPipelineFactory(pfact);
        this.peerHost = remoteHost;
        this.peerPort = remotePort;
        this.connectRetryTime = 0;
    }

    @Override
    public void disconnectPeer() {
        if (connectExecutor != null) {
            connectExecutor.shutdown();
            connectExecutor = null;
        }
    }

    @Override
    public void connectPeer() {
        scheduleConnectionRetry(this.connectRetryTime);
    }

    /**
     * Retry connection with exponential back-off mechanism.
     *
     * @param retryDelay retry delay
     */
    private void scheduleConnectionRetry(long retryDelay) {
        if (this.connectExecutor == null) {
            this.connectExecutor = Executors.newSingleThreadScheduledExecutor();
        }
        this.connectExecutor.schedule(new ConnectionRetry(), retryDelay, TimeUnit.MINUTES);
    }

    /**
     * Implements BGP connection and manages connection to peer with back-off mechanism in case of failure.
     */
    class ConnectionRetry implements Runnable {
        @Override
        public void run() {
            log.debug("Connect to peer {}", peerHost);

            InetSocketAddress connectToSocket = new InetSocketAddress(peerHost, peerPort);

            try {
                bgpconfig.setPeerConnState(peerHost, BgpPeerCfg.State.CONNECT);
                peerBootstrap.connect(connectToSocket).addListener(new ChannelFutureListener() {
                    @Override
                    public void operationComplete(ChannelFuture future) throws Exception {
                        if (!future.isSuccess()) {
                            bgpconfig.setPeerConnState(peerHost, BgpPeerCfg.State.ACTIVE);
                            connectRetryCounter++;
                            log.error("Connection failed, ConnectRetryCounter {} remote host {}", connectRetryCounter,
                                      peerHost);
                            /*
                             * Reconnect to peer on failure is exponential till 4 mins, later on retry after every 4
                             * mins.
                             */
                            if (connectRetryTime < RETRY_INTERVAL) {
                                connectRetryTime = (connectRetryTime != 0) ? connectRetryTime * 2 : 1;
                            }
                            scheduleConnectionRetry(connectRetryTime);
                        } else {

                            connectRetryCounter++;
                            log.info("Connected to remote host {}, Connect Counter {}", peerHost, connectRetryCounter);
                            disconnectPeer();
                            return;
                        }
                    }
                });
            } catch (Exception e) {
                log.info("Connect peer exception : " + e.toString());
                disconnectPeer();
            }
        }
    }
}
