/*
 * Copyright 2016-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.tl1.impl;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.DelimiterBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.util.CharsetUtil;
import org.apache.commons.lang.StringUtils;
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.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.apache.felix.scr.annotations.Service;
import org.onlab.util.Tools;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.DeviceId;
import org.onosproject.tl1.Tl1Command;
import org.onosproject.tl1.Tl1Controller;
import org.onosproject.tl1.Tl1Device;
import org.onosproject.tl1.Tl1Listener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.CopyOnWriteArraySet;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * Implementation of TL1 controller.
 *
 * Handles the connection and input/output for all registered TL1 devices.
 * Turn on debug logging if you want to see all message I/O.
 *
 * Per device, we track commands using a simple ctag-keyed map. This assumes the client is sending out unique ctag's.
 */
@Component(immediate = true)
@Service
public class DefaultTl1Controller implements Tl1Controller {
    private final Logger log = LoggerFactory.getLogger(DefaultTl1Controller.class);

    // TL1 message delimiter (semi colon)
    private static final ByteBuf DELIMITER = Unpooled.copiedBuffer(new char[]{';'}, Charset.defaultCharset());
    private static final String COMPLD = "COMPLD";
    private static final String DENY = "DENY";

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected MastershipService mastershipService;

    private ConcurrentMap<DeviceId, Tl1Device> deviceMap = new ConcurrentHashMap<>();
    // Key: channel, value: map with key ctag, value: future TL1 msg (ctags are assumed unique per device)
    private ConcurrentMap<Channel, ConcurrentMap<Integer, CompletableFuture<String>>> msgMap =
            new ConcurrentHashMap<>();
    private EventLoopGroup workerGroup = new NioEventLoopGroup();
    private Set<Tl1Listener> tl1Listeners = new CopyOnWriteArraySet<>();
    private ExecutorService executor;

    @Activate
    public void activate() {
        executor = Executors.newFixedThreadPool(
                Runtime.getRuntime().availableProcessors(),
                Tools.groupedThreads("onos/tl1controller", "%d", log));
        log.info("Started");
    }

    @Deactivate
    public void deactivate() {
        executor.shutdown();
        deviceMap.clear();
        msgMap.clear();
        log.info("Stopped");
    }

    @Override
    /**
     * This implementation returns an empty string on failure.
     */
    public CompletableFuture<String> sendMsg(DeviceId deviceId, Tl1Command msg) {
        log.debug("Sending TL1 message to device {}: {}", deviceId, msg);

        Tl1Device device = deviceMap.get(deviceId);
        if (device == null || !device.isConnected() || !mastershipService.isLocalMaster(deviceId)) {
            return CompletableFuture.completedFuture(StringUtils.EMPTY);
        }

        // Create and store completable future, complete it in the channel handler when we receive a response
        CompletableFuture<String> future = new CompletableFuture<>();
        Channel channel = device.channel();
        if (!msgMap.containsKey(channel)) {
            return CompletableFuture.completedFuture(StringUtils.EMPTY);
        }
        msgMap.get(channel).put(msg.ctag(), future);

        // Write message to channel
        channel.writeAndFlush(Unpooled.copiedBuffer(msg.toString(), CharsetUtil.UTF_8));

        return future;
    }

    @Override
    public Optional<Tl1Device> getDevice(DeviceId deviceId) {
        return Optional.ofNullable(deviceMap.get(deviceId));
    }

    @Override
    public boolean addDevice(DeviceId deviceId, Tl1Device device) {
        log.debug("Adding TL1 device {} {}", deviceId);

        // Ignore if device already known
        if (deviceMap.containsKey(deviceId)) {
            log.error("Ignoring duplicate device {}", deviceId);
            return false;
        }

        deviceMap.put(deviceId, device);
        return true;
    }

    @Override
    public void connectDevice(DeviceId deviceId) {
        Tl1Device device = deviceMap.get(deviceId);
        if (device == null || device.isConnected()) {
            return;
        }

        Bootstrap b = new Bootstrap();
        b.group(workerGroup)
                .channel(NioSocketChannel.class)
                .option(ChannelOption.SO_KEEPALIVE, true)
                .handler(new ChannelInitializer<SocketChannel>() {
                    @Override
                    protected void initChannel(SocketChannel socketChannel) throws Exception {
                        socketChannel.pipeline().addLast(new DelimiterBasedFrameDecoder(8192, DELIMITER));
                        socketChannel.pipeline().addLast("stringDecoder", new StringDecoder(CharsetUtil.UTF_8));
                        // TODO
                        //socketChannel.pipeline().addLast(new Tl1Decoder());
                        socketChannel.pipeline().addLast(new Tl1InboundHandler());
                    }
                })
                .remoteAddress(device.ip().toInetAddress(), device.port())
                .connect()
                .addListener((ChannelFuture channelFuture) -> {
                    if (channelFuture.isSuccess()) {
                        msgMap.put(channelFuture.channel(), new ConcurrentHashMap<>());
                        device.connect(channelFuture.channel());
                        tl1Listeners.forEach(l -> executor.execute(() -> l.deviceConnected(deviceId)));
                    }
                });
    }

    @Override
    public void removeDevice(DeviceId deviceId) {
        disconnectDevice(deviceId);
        deviceMap.remove(deviceId);
    }

    @Override
    public void addListener(Tl1Listener listener) {
        tl1Listeners.add(listener);
    }

    @Override
    public void removeListener(Tl1Listener listener) {
        tl1Listeners.remove(listener);
    }

    @Override
    public void disconnectDevice(DeviceId deviceId) {
        // Ignore if unknown device
        Tl1Device device = deviceMap.get(deviceId);
        if (device == null) {
            return;
        }

        Channel channel = device.channel();
        if (channel != null) {
            channel.close();
        }

        msgMap.remove(channel);
        device.disconnect();
        tl1Listeners.forEach(l -> l.deviceDisconnected(deviceId));
    }

    @Override
    public Set<DeviceId> getDeviceIds() {
        return deviceMap.keySet();
    }

    @Override
    public Collection<Tl1Device> getDevices() {
        return deviceMap.values();
    }

    /**
     * Crude filtering handler that will only complete our stored future upon receiving a TL1 response messages.
     */
    private class Tl1InboundHandler extends SimpleChannelInboundHandler<String> {
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, String s) throws Exception {
            log.debug("Received TL1 message {}", s);

            // Search for "COMPLD" or "DENY" to identify a TL1 response,
            // then return the remainder of the string.
            String[] words = s.split("\\s");
            for (int i = 0; i < words.length; i++) {
                String w = words[i];
                if (w.startsWith(COMPLD) || w.startsWith(DENY)) {
                    // ctag is just in front of it
                    int ctag = Integer.parseInt(words[i - 1]);
                    // We return everything that follows to the caller (this will lose line breaks and such)
                    String result = Arrays.stream(words).skip(i + 1).collect(Collectors.joining());
                    // Set future when command is executed, good or bad
                    Map<Integer, CompletableFuture<String>> msg = msgMap.get(ctx.channel());
                    if (msg != null) {
                        CompletableFuture<String> f = msg.remove(ctag);
                        if (f != null) {
                            f.complete(result);
                        }
                    }

                    return;
                }
            }
        }
    }
}
