/*
 * 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.store.proxyarp.impl;

import com.google.common.collect.Maps;
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.KryoNamespace;
import org.onosproject.cluster.ClusterService;
import org.onosproject.cluster.NodeId;
import org.onosproject.mastership.MastershipService;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.Host;
import org.onosproject.net.HostId;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostService;
import org.onosproject.net.proxyarp.ProxyArpStore;
import org.onosproject.net.proxyarp.ProxyArpStoreDelegate;
import org.onosproject.store.cluster.messaging.ClusterCommunicationService;
import org.onosproject.store.cluster.messaging.MessageSubject;
import org.onosproject.store.serializers.KryoNamespaces;
import org.onosproject.store.serializers.KryoSerializer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.nio.ByteBuffer;
import java.util.Map;
import java.util.concurrent.ExecutorService;

import static org.onlab.util.BoundedThreadPool.newFixedThreadPool;
import static org.onlab.util.Tools.groupedThreads;

/**
 * Implementation of proxy ARP distribution mechanism.
 */
@Component(immediate = true)
@Service
public class DistributedProxyArpStore implements ProxyArpStore {

    private Logger log = LoggerFactory.getLogger(getClass());

    private static final MessageSubject ARP_RESPONSE_MESSAGE =
            new MessageSubject("onos-arp-response");

    protected final KryoSerializer serializer = new KryoSerializer() {
        @Override
        protected void setupKryoPool() {
            serializerPool = KryoNamespace.newBuilder()
                    .register(KryoNamespaces.API)
                    .register(ArpResponseMessage.class)
                    .register(ByteBuffer.class)
                    .build();
        }
    };

    private ProxyArpStoreDelegate delegate;

    private Map<HostId, ArpResponseMessage> pendingMessages = Maps.newConcurrentMap();

    private ExecutorService executor =
            newFixedThreadPool(4, groupedThreads("onos/arp", "sender-%d"));

    private NodeId localNodeId;

    private HostListener hostListener = new InternalHostListener();

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ClusterService clusterService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ClusterCommunicationService commService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected HostService hostService;


    @Activate
    protected void activate() {
        localNodeId = clusterService.getLocalNode().id();
        hostService.addListener(hostListener);
        commService.addSubscriber(ARP_RESPONSE_MESSAGE, serializer::decode,
                                  this::processArpResponse, executor);
        log.info("Started");
    }

    @Deactivate
    protected void deactivate() {
        commService.removeSubscriber(ARP_RESPONSE_MESSAGE);
        hostService.removeListener(hostListener);
        log.info("Stopped");
    }

    @Override
    public void forward(ConnectPoint outPort, Host subject, ByteBuffer packet) {
        /*NodeId nodeId = mastershipService.getMasterFor(outPort.deviceId());
        if (nodeId.equals(localNodeId)) {
            if (delegate != null) {
                delegate.emitResponse(outPort, packet);
            }
        } else {
            log.info("Forwarding ARP response from {} to {}", subject.id(), outPort);
            commService.unicast(new ArpResponseMessage(outPort, subject, packet.array()),
                                ARP_RESPONSE_MESSAGE, serializer::encode, nodeId);
        }*/
        //FIXME: Code above may be unnecessary and therefore cluster messaging
        // and pendingMessages could be pruned as well.
        delegate.emitResponse(outPort, packet);
    }

    @Override
    public void setDelegate(ProxyArpStoreDelegate delegate) {
        this.delegate = delegate;
    }

    // Processes the incoming ARP response message.
    private void processArpResponse(ArpResponseMessage msg) {
        pendingMessages.put(msg.subject.id(), msg);
        if (hostService.getHost(msg.subject.id()) != null) {
            checkPendingArps(msg.subject.id());
        }
        // FIXME: figure out pruning so stuff does not build up
    }

    // Checks for pending ARP response message for the specified host.
    // If one exists, emit response via delegate.
    private void checkPendingArps(HostId id) {
        ArpResponseMessage msg = pendingMessages.remove(id);
        if (msg != null && delegate != null) {
            log.info("Emitting ARP response from {} to {}", id, msg.outPort);
            delegate.emitResponse(msg.outPort, ByteBuffer.wrap(msg.packet));
        }
    }

    // Message carrying an ARP response.
    private static class ArpResponseMessage {
        private ConnectPoint outPort;
        private Host subject;
        private byte[] packet;

        public ArpResponseMessage(ConnectPoint outPort, Host subject, byte[] packet) {
            this.outPort = outPort;
            this.subject = subject;
            this.packet = packet;
        }

        private ArpResponseMessage() {
        }
    }

    private class InternalHostListener implements HostListener {
        @Override
        public void event(HostEvent event) {
            checkPendingArps(event.subject().id());
        }
    }
}
