/*
 * 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 com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory;
import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree;
import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree;
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.packet.ARP;
import org.onlab.packet.Ethernet;
import org.onlab.packet.Ip4Address;
import org.onlab.packet.Ip6Address;
import org.onlab.packet.IpAddress;
import org.onlab.packet.IpPrefix;
import org.onlab.packet.IPv6;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
import org.onlab.packet.ndp.NeighborSolicitation;
import org.onosproject.app.ApplicationService;
import org.onosproject.core.ApplicationId;
import org.onosproject.core.CoreService;
import org.onosproject.component.ComponentService;
import org.onosproject.event.ListenerRegistry;
import org.onosproject.net.intf.Interface;
import org.onosproject.net.intf.InterfaceService;
import org.onosproject.net.intf.InterfaceListener;
import org.onosproject.net.intf.InterfaceEvent;
import org.onosproject.net.config.ConfigFactory;
import org.onosproject.net.config.NetworkConfigEvent;
import org.onosproject.net.config.NetworkConfigListener;
import org.onosproject.net.config.NetworkConfigRegistry;
import org.onosproject.net.config.NetworkConfigService;
import org.onosproject.net.config.basics.SubjectFactories;
import org.onosproject.net.ConnectPoint;
import org.onosproject.net.device.DeviceEvent;
import org.onosproject.net.device.DeviceListener;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.net.Host;
import org.onosproject.net.host.HostService;
import org.onosproject.net.host.HostListener;
import org.onosproject.net.host.HostEvent;
import org.onosproject.net.packet.PacketService;
import org.onosproject.net.packet.DefaultOutboundPacket;
import org.onosproject.net.packet.OutboundPacket;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.OutputStream;
import java.io.PrintStream;
import java.nio.ByteBuffer;
import java.util.HashSet;
import java.util.Collection;
import java.util.Set;
import java.util.Map;

import static org.onosproject.simplefabric.RouteTools.createBinaryString;


/**
 * Reactive routing configuration manager.
 */
@Component(immediate = true)
@Service
public class SimpleFabricManager extends ListenerRegistry<SimpleFabricEvent, SimpleFabricListener>
        implements SimpleFabricService {

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

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ApplicationService applicationService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected NetworkConfigService configService;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected NetworkConfigRegistry registry;

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected DeviceService deviceService;

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

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

    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected PacketService packetService;

    // compoents to be activated within SimpleFabric
    @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
    protected ComponentService componentService;

    // SimpleFabric variables
    private ApplicationId appId = null;

    // l2 broadcast networks
    private Set<L2Network> l2Networks = new HashSet<>();
    private Set<Interface> l2NetworkInterfaces = new HashSet<>();

    // Subnet table
    private Set<IpSubnet> ipSubnets = new HashSet<>();
    private InvertedRadixTree<IpSubnet> ip4SubnetTable =
                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
    private InvertedRadixTree<IpSubnet> ip6SubnetTable =
                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());

    // Border Route table
    private Set<Route> borderRoutes = new HashSet<>();
    private InvertedRadixTree<Route> ip4BorderRouteTable =
                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
    private InvertedRadixTree<Route> ip6BorderRouteTable =
                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());

    // VirtialGateway
    private Map<IpAddress, MacAddress> virtualGatewayIpMacMap = Maps.newConcurrentMap();

    // Refresh monitor thread
    private Object refreshMonitor = new Object();
    private boolean doRefresh = false;
    private boolean doFlush = false;
    private InternalRefreshThread refreshThread;

    // Listener for Service Events
    private final InternalNetworkConfigListener configListener = new InternalNetworkConfigListener();
    private final InternalDeviceListener deviceListener = new InternalDeviceListener();
    private final InternalHostListener hostListener = new InternalHostListener();
    private final InternalInterfaceListener interfaceListener = new InternalInterfaceListener();

    private ConfigFactory<ApplicationId, SimpleFabricConfig> simpleFabricConfigFactory =
        new ConfigFactory<ApplicationId, SimpleFabricConfig>(
                SubjectFactories.APP_SUBJECT_FACTORY,
                SimpleFabricConfig.class, SimpleFabricConfig.KEY) {
        @Override
        public SimpleFabricConfig createConfig() {
            return new SimpleFabricConfig();
       }
    };

    @Activate
    public void activate() {
        log.info("simple fabric starting");

        if (appId == null) {
            appId = coreService.registerApplication(APP_ID);
        }

        // initial refresh
        refresh();

        configService.addListener(configListener);
        registry.registerConfigFactory(simpleFabricConfigFactory);
        deviceService.addListener(deviceListener);
        hostService.addListener(hostListener);

        componentService.activate(appId, SimpleFabricNeighbour.class.getName());
        componentService.activate(appId, SimpleFabricReactiveRouting.class.getName());
        if (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) {
            componentService.activate(appId, SimpleFabricL2Forward.class.getName());
        }

        refreshThread = new InternalRefreshThread();
        refreshThread.start();

        log.info("simple fabric started");
    }

    @Deactivate
    public void deactivate() {
        log.info("simple fabric stopping");

        componentService.deactivate(appId, SimpleFabricNeighbour.class.getName());
        componentService.deactivate(appId, SimpleFabricReactiveRouting.class.getName());
        if (SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR) {
            componentService.deactivate(appId, SimpleFabricL2Forward.class.getName());
        }

        deviceService.removeListener(deviceListener);
        hostService.removeListener(hostListener);
        registry.unregisterConfigFactory(simpleFabricConfigFactory);
        configService.removeListener(configListener);

        refreshThread.stop();
        refreshThread = null;

        log.info("simple fabric stopped");
    }

    // Set up from configuration
    // returns found dirty and refresh listners are called (true) or not (false)
    private boolean refresh() {
        log.debug("simple fabric refresh");
        boolean dirty = false;

        SimpleFabricConfig config = configService.getConfig(coreService.registerApplication(APP_ID),
                                                            SimpleFabricConfig.class);
        if (config == null) {
            log.debug("No reactive routing config available!");
            return false;
        }

        // l2Networks
        Set<L2Network> newL2Networks = new HashSet<>();
        Set<Interface> newL2NetworkInterfaces = new HashSet<>();
        for (L2Network newL2NetworkConfig : config.getL2Networks()) {
            L2Network newL2Network = L2Network.of(newL2NetworkConfig);

            // fill up interfaces and Hosts with active port only
            for (String ifaceName : newL2NetworkConfig.interfaceNames()) {
                Interface iface = getInterfaceByName(ifaceName);
                if (iface != null && deviceService.isAvailable(iface.connectPoint().deviceId())) {
                     newL2Network.addInterface(iface);
                     newL2NetworkInterfaces.add(iface);
                }
            }
            for (Host host : hostService.getHosts()) {
                // consider host with ip only
                if (!host.ipAddresses().isEmpty()) {
                    Interface iface = findAvailableDeviceHostInterface(host);
                    if (iface != null && newL2Network.contains(iface)) {
                        newL2Network.addHost(host);
                    }
                }
            }
            newL2Network.setDirty(true);

            // update newL2Network's dirty flags if same entry already exists
            for (L2Network prevL2Network : l2Networks) {
                if (prevL2Network.equals(newL2Network)) {
                    newL2Network.setDirty(prevL2Network.dirty());
                    break;
                }
            }
            newL2Networks.add(newL2Network);
        }
        if (!l2Networks.equals(newL2Networks)) {
            l2Networks = newL2Networks;
            dirty = true;
        }
        if (!l2NetworkInterfaces.equals(newL2NetworkInterfaces)) {
            l2NetworkInterfaces = newL2NetworkInterfaces;
            dirty = true;
        }

        // ipSubnets
        Set<IpSubnet> newIpSubnets = config.ipSubnets();
        InvertedRadixTree<IpSubnet> newIp4SubnetTable =
                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
        InvertedRadixTree<IpSubnet> newIp6SubnetTable =
                 new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
        Map<IpAddress, MacAddress> newVirtualGatewayIpMacMap = Maps.newConcurrentMap();
        for (IpSubnet subnet : newIpSubnets) {
            if (subnet.ipPrefix().isIp4()) {
                newIp4SubnetTable.put(createBinaryString(subnet.ipPrefix()), subnet);
            } else {
                newIp6SubnetTable.put(createBinaryString(subnet.ipPrefix()), subnet);
            }
            newVirtualGatewayIpMacMap.put(subnet.gatewayIp(), subnet.gatewayMac());
        }
        if (!ipSubnets.equals(newIpSubnets)) {
            ipSubnets = newIpSubnets;
            ip4SubnetTable = newIp4SubnetTable;
            ip6SubnetTable = newIp6SubnetTable;
            dirty = true;
        }
        if (!virtualGatewayIpMacMap.equals(newVirtualGatewayIpMacMap)) {
            virtualGatewayIpMacMap = newVirtualGatewayIpMacMap;
            dirty = true;
        }

        // borderRoutes config handling
        Set<Route> newBorderRoutes = config.borderRoutes();
        if (!borderRoutes.equals(newBorderRoutes)) {
            InvertedRadixTree<Route> newIp4BorderRouteTable =
                    new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
            InvertedRadixTree<Route> newIp6BorderRouteTable =
                    new ConcurrentInvertedRadixTree<>(new DefaultByteArrayNodeFactory());
            for (Route route : newBorderRoutes) {
                if (route.prefix().isIp4()) {
                    newIp4BorderRouteTable.put(createBinaryString(route.prefix()), route);
                } else {
                    newIp6BorderRouteTable.put(createBinaryString(route.prefix()), route);
                }
            }
            borderRoutes = newBorderRoutes;
            ip4BorderRouteTable = newIp4BorderRouteTable;
            ip6BorderRouteTable = newIp6BorderRouteTable;
            dirty = true;
        }

        // notify to SimpleFabric listeners
        if (dirty) {
            log.info("simple fabric refresh; notify events");
            process(new SimpleFabricEvent(SimpleFabricEvent.Type.SIMPLE_FABRIC_UPDATED, "updated"));
        }
        return dirty;
    }

    private Interface getInterfaceByName(String interfaceName) {
        Interface intf = interfaceService.getInterfaces().stream()
                          .filter(iface -> iface.name().equals(interfaceName))
                          .findFirst()
                          .orElse(null);
        if (intf == null) {
            log.warn("simple fabric unknown interface name: {}", interfaceName);
        }
        return intf;
    }

    @Override
    public ApplicationId getAppId() {
        if (appId == null) {
            appId = coreService.registerApplication(APP_ID);
        }
        return appId;
    }

    @Override
    public Collection<L2Network> getL2Networks() {
        return ImmutableSet.copyOf(l2Networks);
    }

    @Override
    public Set<IpSubnet> getIpSubnets() {
        return ImmutableSet.copyOf(ipSubnets);
    }

    @Override
    public Set<Route> getBorderRoutes() {
        return ImmutableSet.copyOf(borderRoutes);
    }

    @Override
    public boolean isVMac(MacAddress mac) {
        return virtualGatewayIpMacMap.containsValue(mac);
    }

    @Override
    public boolean isL2NetworkInterface(Interface intf) {
        return l2NetworkInterfaces.contains(intf);
    }

    @Override
    public MacAddress findVMacForIp(IpAddress ip) {
        return virtualGatewayIpMacMap.get(ip);
    }

    @Override
    public L2Network findL2Network(ConnectPoint port, VlanId vlanId) {
        for (L2Network l2Network : l2Networks) {
            if (l2Network.contains(port, vlanId)) {
                return l2Network;
            }
        }
        return null;
    }

    @Override
    public L2Network findL2Network(String name) {
        for (L2Network l2Network : l2Networks) {
            if (l2Network.name().equals(name)) {
                return l2Network;
            }
        }
        return null;
    }

    @Override
    public IpSubnet findIpSubnet(IpAddress ip) {
        if (ip.isIp4()) {
            return ip4SubnetTable.getValueForLongestKeyPrefixing(
                     createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH)));
        } else {
            return ip6SubnetTable.getValueForLongestKeyPrefixing(
                     createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH)));
        }
    }

    @Override
    public Route findBorderRoute(IpAddress ip) {
        // ASSUME: ipAddress is out of ipSubnet
        if (ip.isIp4()) {
            return ip4BorderRouteTable.getValueForLongestKeyPrefixing(
                     createBinaryString(IpPrefix.valueOf(ip, Ip4Address.BIT_LENGTH)));
        } else {
            return ip6BorderRouteTable.getValueForLongestKeyPrefixing(
                     createBinaryString(IpPrefix.valueOf(ip, Ip6Address.BIT_LENGTH)));
        }
    }


    @Override
    public Interface findHostInterface(Host host) {
        return interfaceService.getInterfaces().stream()
                .filter(iface -> iface.connectPoint().equals(host.location()) &&
                                 iface.vlan().equals(host.vlan()))
                .findFirst()
                .orElse(null);
    }

    private Interface findAvailableDeviceHostInterface(Host host) {
        return interfaceService.getInterfaces().stream()
                .filter(iface -> iface.connectPoint().equals(host.location()) &&
                                 iface.vlan().equals(host.vlan()))
                .filter(iface -> deviceService.isAvailable(iface.connectPoint().deviceId()))
                .findFirst()
                .orElse(null);
    }

    @Override
    public boolean requestMac(IpAddress ip) {
        IpSubnet ipSubnet = findIpSubnet(ip);
        if (ipSubnet == null) {
            log.warn("simple fabric request mac failed for unknown IpSubnet: {}", ip);
            return false;
        }
        L2Network l2Network = findL2Network(ipSubnet.l2NetworkName());
        if (l2Network == null) {
            log.warn("simple fabric request mac failed for unknown l2Network name {}: {}",
                     ipSubnet.l2NetworkName(), ip);
            return false;
        }
        log.debug("simple fabric send request mac L2Network {}: {}", l2Network.name(), ip);
        for (Interface iface : l2Network.interfaces()) {
            Ethernet neighbourReq;
            if (ip.isIp4()) {
                neighbourReq = ARP.buildArpRequest(ipSubnet.gatewayMac().toBytes(),
                                                   ipSubnet.gatewayIp().toOctets(),
                                                   ip.toOctets(),
                                                   iface.vlan().toShort());
            } else {
                byte[] soliciteIp = IPv6.getSolicitNodeAddress(ip.toOctets());
                neighbourReq = NeighborSolicitation.buildNdpSolicit(
                                                   ip.toOctets(),
                                                   ipSubnet.gatewayIp().toOctets(),
                                                   soliciteIp,
                                                   ipSubnet.gatewayMac().toBytes(),
                                                   IPv6.getMCastMacAddress(soliciteIp),
                                                   iface.vlan());
            }
            TrafficTreatment treatment = DefaultTrafficTreatment.builder()
                                               .setOutput(iface.connectPoint().port()).build();
            OutboundPacket packet = new DefaultOutboundPacket(iface.connectPoint().deviceId(),
                                               treatment, ByteBuffer.wrap(neighbourReq.serialize()));
            packetService.emit(packet);
        }
        return true;
    }

    @Override
    public void dumpToStream(String subject, OutputStream out) {
        SimpleFabricEvent event = new SimpleFabricEvent(SimpleFabricEvent.Type.SIMPLE_FABRIC_DUMP, subject, out);
        dump(event.subject(), event.out());  // dump in itself
        process(event);  // dump in sub modules
    }

    // Dump handler
    protected void dump(String subject, PrintStream out) {
        if ("show".equals(subject)) {
            out.println("Static Configuration Flag:");
            out.println("    ALLOW_IPV6="
                        + SimpleFabricService.ALLOW_IPV6);
            out.println("    ALLOW_ETH_ADDRESS_SELECTOR="
                        + SimpleFabricService.ALLOW_ETH_ADDRESS_SELECTOR);
            out.println("    REACTIVE_SINGLE_TO_SINGLE="
                        + SimpleFabricService.REACTIVE_SINGLE_TO_SINGLE);
            out.println("    REACTIVE_ALLOW_LINK_CP="
                        + SimpleFabricService.REACTIVE_ALLOW_LINK_CP);
            out.println("    REACTIVE_HASHED_PATH_SELECTION="
                        + SimpleFabricService.REACTIVE_HASHED_PATH_SELECTION);
            out.println("    REACTIVE_MATCH_IP_PROTO="
                        + SimpleFabricService.REACTIVE_MATCH_IP_PROTO);
            out.println("");
            out.println("SimpleFabricAppId:");
            out.println("    " + getAppId());
            out.println("");
            out.println("l2Networks:");
            for (L2Network l2Network : getL2Networks()) {
                out.println("    " + l2Network);
            }
            out.println("");
            out.println("ipSubnets:");
            for (IpSubnet ipSubnet : getIpSubnets()) {
                out.println("    " + ipSubnet);
            }
            out.println("");
            out.println("borderRoutes:");
            for (Route route : getBorderRoutes()) {
                out.println("    " + route);
            }
        }
    }

    // Refresh action thread and notifier

    private class InternalRefreshThread extends Thread {
        public void run() {
            while (true) {
                boolean doRefreshMarked = false;
                boolean doFlushMarked = false;
                synchronized (refreshMonitor) {
                    if (!doRefresh && !doFlush) {
                        try {
                            refreshMonitor.wait(IDLE_INTERVAL_MSEC);
                        } catch (InterruptedException e) {
                            log.warn("run thread interrupted", e);
                            Thread.currentThread().interrupt();
                        }
                    }
                    doRefreshMarked = doRefresh;
                    doRefresh = false;
                    doFlushMarked = doFlush;
                    doFlush = false;
                }
                if (doRefreshMarked) {
                    try {
                        refresh();
                    } catch (Exception e) {
                        log.warn("simple fabric refresh failed: exception={}", e);
                    }
                }
                if (doFlushMarked) {
                    try {
                        log.info("simple fabric flush execute");
                        process(new SimpleFabricEvent(SimpleFabricEvent.Type.SIMPLE_FABRIC_FLUSH, "flush"));
                    } catch (Exception e) {
                        log.warn("simple fabric flush failed: exception={}", e);
                    }
                }
                if (!doRefreshMarked && !doFlushMarked) {
                    try {
                        if (!refresh()) {
                            process(new SimpleFabricEvent(SimpleFabricEvent.Type.SIMPLE_FABRIC_IDLE, "idle"));
                        }
                    } catch (Exception e) {
                        log.warn("simple fabric idle failed: exception={}", e);
                    }
                }
            }
        }
    }

    @Override
    public void triggerRefresh() {
        synchronized (refreshMonitor) {
            doRefresh = true;
            refreshMonitor.notifyAll();
        }
    }

    @Override
    public void triggerFlush() {
        synchronized (refreshMonitor) {
            doFlush = true;
            refreshMonitor.notifyAll();
        }
    }

    // Service Listeners

    private class InternalNetworkConfigListener implements NetworkConfigListener {
        @Override
        public void event(NetworkConfigEvent event) {
            switch (event.type()) {
            case CONFIG_REGISTERED:
            case CONFIG_UNREGISTERED:
            case CONFIG_ADDED:
            case CONFIG_UPDATED:
            case CONFIG_REMOVED:
                if (event.configClass().equals(SimpleFabricConfig.class)) {
                    triggerRefresh();
                }
                break;
            default:
                break;
            }
        }
    }

    private class InternalDeviceListener implements DeviceListener {
        @Override
        public void event(DeviceEvent event) {
            switch (event.type()) {
            case DEVICE_ADDED:
            case DEVICE_AVAILABILITY_CHANGED:
            case DEVICE_REMOVED:
            case DEVICE_SUSPENDED:
            case DEVICE_UPDATED:
            case PORT_ADDED:
            case PORT_REMOVED:
            case PORT_UPDATED:
            // case PORT_STATS_UPDATED:  IGNORED
                triggerRefresh();
                break;
            default:
                break;
            }
        }
    }

    private class InternalHostListener implements HostListener {
        @Override
        public void event(HostEvent event) {
            Host host = event.subject();
            Host prevHost = event.prevSubject();
            switch (event.type()) {
            case HOST_MOVED:
            case HOST_REMOVED:
            case HOST_ADDED:
            case HOST_UPDATED:
                triggerRefresh();
                break;
            default:
                break;
            }
        }
    }

    private class InternalInterfaceListener implements InterfaceListener {
        @Override
        public void event(InterfaceEvent event) {
            Interface iface = event.subject();
            Interface prevIface = event.prevSubject();
            switch (event.type()) {
            case INTERFACE_ADDED:
            case INTERFACE_REMOVED:
            case INTERFACE_UPDATED:
                triggerRefresh();
                break;
            default:
                break;
            }
        }
    }

}

