/*
 * Copyright 2017-present Open Networking Foundation
 *
 * 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.simplefabric;

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.onlab.packet.MacAddress;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.net.intf.Interface;
import org.onosproject.net.intf.InterfaceService;
import org.onosproject.net.neighbour.NeighbourMessageContext;
import org.onosproject.net.neighbour.NeighbourMessageHandler;
import org.onosproject.net.neighbour.NeighbourResolutionService;
import org.onosproject.net.Host;
import org.onosproject.net.host.HostService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;


/**
 * Handles neighbour messages for on behalf of the L2 Network application. Handlers
 * will be changed automatically by interface or network configuration events.
 */
@Component(immediate = true, enabled = false)
public class SimpleFabricNeighbour {

    private final Logger log = LoggerFactory.getLogger(getClass());
    protected ApplicationId appId;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected CoreService coreService;

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected InterfaceService interfaceService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected NeighbourResolutionService neighbourService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected SimpleFabricService simpleFabric;

    private final InternalSimpleFabricListener simpleFabricListener =
            new InternalSimpleFabricListener();

    private L2NetworkNeighbourMessageHandler neighbourHandler =
            new L2NetworkNeighbourMessageHandler();

    private Set<Interface> monitoredInterfaces = new HashSet<>();

    @Activate
    public void activate() {
        appId = simpleFabric.getAppId();
        simpleFabric.addListener(simpleFabricListener);
        refresh();
        log.info("simple fabric neighbour started");
    }

    @Deactivate
    public void deactivate() {
        simpleFabric.removeListener(simpleFabricListener);
        unregister();
        monitoredInterfaces.clear();
        log.info("simple fabric neighbour stoped");
    }

    /**
     * Registers neighbour handler to all available interfaces.
     */
    protected void refresh() {
        Set<Interface> interfaces = interfaceService.getInterfaces();
        // check for new interfaces
        for (Interface intf : interfaces) {
            if (!monitoredInterfaces.contains(intf) && simpleFabric.isL2NetworkInterface(intf)) {
               log.info("simple fabric neighbour register handler: {}", intf);
               neighbourService.registerNeighbourHandler(intf, neighbourHandler, appId);
               monitoredInterfaces.add(intf);
            } else {
               log.debug("simple fabric neighobur unknown interface: {}", intf);
            }
        }
        // check for removed interfaces
        Set<Interface> monitoredInterfacesToBeRemoved = new HashSet<>();
        for (Interface intf : monitoredInterfaces) {
            if (!interfaces.contains(intf)) {
               log.info("simple fabric neighbour unregister handler: {}", intf);
               neighbourService.unregisterNeighbourHandler(intf, neighbourHandler, appId);
               monitoredInterfacesToBeRemoved.add(intf);
            }
        }
        for (Interface intf : monitoredInterfacesToBeRemoved) {
            monitoredInterfaces.remove(intf);
        }
    }

    /**
     * Unregisters neighbour handler to all available interfaces.
     */
    protected void unregister() {
        log.info("simple fabric neighbour unregister handler");
        neighbourService.unregisterNeighbourHandlers(appId);
    }

    /**
     * Handles request messages.
     *
     * @param context the message context
     */
    protected void handleRequest(NeighbourMessageContext context) {
        MacAddress mac = simpleFabric.getVMacForIp(context.target());
        if (mac != null) {
            log.trace("simple fabric neightbour request on virtualGatewayAddress {}; response to {} {} mac={}",
                      context.target(), context.inPort(), context.vlan(), mac);
            context.reply(mac);
            return;
        }
        // else forward to corresponding host

        L2Network l2Network = simpleFabric.findL2Network(context.inPort(), context.vlan());
        if (l2Network != null) {
            int numForwards = 0;
            if (!context.dstMac().isBroadcast() && !context.dstMac().isMulticast()) {
                for (Host host : hostService.getHostsByMac(context.dstMac())) {
                    log.trace("simple fabric neightbour request forward unicast to {}", host.location());
                    context.forward(host.location());  // ASSUME: vlan is same
                    // TODO: may need to check host.location().time()
                    numForwards++;
                }
                if (numForwards > 0) {
                    return;
                }
            }
            // else do broadcast to all host in the same l2 network
            log.trace("simple fabric neightbour request forward broadcast: {} {}",
                     context.inPort(), context.vlan());
            for (Interface iface : l2Network.interfaces()) {
                if (!context.inPort().equals(iface.connectPoint())) {
                    log.trace("simple fabric forward neighbour request broadcast to {}", iface);
                    context.forward(iface);
                }
            }
        } else {
            log.warn("simple fabric neightbour request drop: {} {}",
                     context.inPort(), context.vlan());
            context.drop();
        }
    }

    /**
     * Handles reply messages between VLAN tagged interfaces.
     *
     * @param context the message context
     * @param hostService the host service
     */
    protected void handleReply(NeighbourMessageContext context,
                               HostService hostService) {
        // Find target L2 Network, then reply to the host
        L2Network l2Network = simpleFabric.findL2Network(context.inPort(), context.vlan());
        if (l2Network != null) {
            // TODO: need to check and update simpleFabric.L2Network
            MacAddress mac = simpleFabric.getVMacForIp(context.target());
            if (mac != null) {
                log.trace("simple fabric neightbour response message to virtual gateway; drop: {} {} target={}",
                          context.inPort(), context.vlan(), context.target());
                context.drop();
            } else {
                // forward reply to the hosts of the dstMac
                Set<Host> hosts = hostService.getHostsByMac(context.dstMac());
                log.trace("simple fabric neightbour response message forward: {} {} target={} -> {}",
                          context.inPort(), context.vlan(), context.target(), hosts);
                hosts.stream()
                        .map(host -> simpleFabric.getHostInterface(host))
                        .filter(Objects::nonNull)
                        .forEach(context::forward);
            }
        } else {
            // this might be happened when we remove an interface from L2 Network
            // just ignore this message
            log.warn("simple fabric neightbour response message drop for unknown l2Network: {} {}",
                     context.inPort(), context.vlan());
            context.drop();
        }
    }

    private class L2NetworkNeighbourMessageHandler implements NeighbourMessageHandler {
        @Override
        public void handleMessage(NeighbourMessageContext context,
                                  HostService hostService) {
            switch (context.type()) {
                case REQUEST:
                    handleRequest(context);
                    break;
                case REPLY:
                    handleReply(context, hostService);
                    break;
                default:
                    log.warn("simple fabric neightor unknown context type: {}", context.type());
                    break;
            }
        }
    }

    private class InternalSimpleFabricListener implements SimpleFabricListener {
        @Override
        public void event(SimpleFabricEvent event) {
            switch (event.type()) {
            case SIMPLE_FABRIC_UPDATED:
                refresh();
                break;
            default:
                break;
            }
        }
    }

}

